-
-
Notifications
You must be signed in to change notification settings - Fork 765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconsider shared_context_metadata_behavior
#2832
Comments
I'd love to summon @myronmarston as the driving force behind |
Thanks for writing this up @pirj and summoning me to comment :). I still think that implicit inclusion of shared example groups via metadata still has problems. #1790 outlines the problems I saw with it when I wrote up that issue. Overall, the implicit inclusion behavior feels inconsistent with the rest of RSpec, IMO; consider that all other ways that RSpec metadata is leveraged you configure it in an
The exact semantic of tagging a shared example group with metadata is something that I'd expect 99% of RSpec users to never think about and the confusing situation the newer behavior solves are relatively rare....so I'm not surprised by that at all. TBH, I suspect For users who want to trigger shared example group inclusion based on metadata, the
Here's how I've used it:
LOL :). I'm not too surprised by that; we haven't historically upgraded RSpec to all of the latest "standard" config settings, etc, particularly if the issues the new config settings address don't happen within RSpec's tests. It's easy enough to change the rspec-expectations metadata-triggered inclusion to use
I'd honestly be surprised if there are more than a handful of users who have thought about how exactly they want shared example group metadata to behave, to then go and set the config option to the behavior they want. I imagine nearly all usages of I don't think that's necessarily an argument against
I think This is basically the crux of why I think
That's by design. IMO, it would be surprising (and weird) to automatically include some shared examples in many example groups based on contexts. A user could look at the spec file, see 4 Anyhow, that's my two cents :). Since I'm no longer involved in maintaining RSpec, do not feel obligated to give my opinion undue weight. |
Thanks a lot for such a detailed and insightful answer, @myronmarston!
That indeed would be an apotheosis of confusion. My doubts are dispelled, I'm going to proceed with making |
It might be worth removing the config option entirely, given the plan is to not support any other behavior. Or maybe for backwards compatibility it could be defined but ignored (although that could be confusing if the user configured the legacy behavior...). I don't know if y'all are planning on releasing an RSpec 3.99 (like we did with 2.99) to provide upgrade warnings, but if you go that route 3.99 could retain the option and warn appropriately and 4.0 could not have the option at all perhaps. |
Thanks for the detailed reply @myronmarston 😂 I'm closing this because I agree, and judging from Phil's PRs he has been convinced also. |
Fixes rspec/rspec-core#2832 --- This commit was imported from rspec/rspec-core@72e4fd9.
Fixes rspec/rspec-core#2775 Related: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#1762 --- This commit was imported from rspec/rspec-core@361e521.
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Starting from RSpec 4, the implicit shared context inclusion, when a shared context would have been included to an example if the example has matching metadata, is not the case anymore. See: - rspec/rspec-core#2834 - rspec/rspec-core#2832 - rspec/rspec-core#2878
Background
We have had a problem with metadata defined on spec-local shared example groups (
shared_examples
/shared_examples_for
/shared_context
) causing them to be included in completely unrelated example group reported in [1]/[2]. Some more information in #1762.In #1790 (ed2d59c),
shared_context_metadata_behavior
with an non-default:apply_to_host_groups
value. 3589ab5 added it to the project initializer along with a note that it will become the default and only option in RSpec 4.:trigger_inclusion
remained the default setting, though, for SemVer reasons.In a nutshell:
Usage
Personally, I've never seen
:apply_to_host_groups
being used the way it was designed for. On the other hand, I've seen some projects use:trigger_inclusion
for globally-defined shared example groups/contexts.But it's a sample of one. Let's check around.
As a sandbox for new
rubocop-rspec
cops, I've assembled a list of most starred Ruby projects that use RSpec,real-world-rspec
, ~35 projects total. Out of those 35 (it includes RSpec repos, too!), 7 use:apply_to_host_groups
in their spec helpers:24pullrequests/ administrate/ Homebrew/ camaleon-cms/ canvas-lms/ capistrano/ capybara/ cartodb/ chatwoot/ chef/ diaspora/ discourse/ locomotivecms/ errbit/ fat_free_crm/ forem/ gitlabhq/ hound/ huginn/ lobsters/ loomio/ mastodon/ open-source-billing/ publify/ puppet/ radiant/ refinerycms/ rspec-core/ rspec-expectations/ rspec-mocks/ rspec-rails/ rubocop/ rubytoolbox/ sharetribe/ solidus/ spree/
And one in
lib
:Others, since they don't have this setting and the default is
:trigger_inclusion
, either don't use shared example groups metadata, or rely on triggering inclusion.Let's take a look at usages. Open this spoiler to see **all** 40 shared groups/contexts with metadata (out of ~3000 total shared groups)
If we make an intersection with the previous list (rspec-rails, lobsters, rubytoolbox, forem, gitlabhq, chatwoot), it turns out that no project uses
:apply_to_host_groups
.gitlabhq
might be a bit confusing, they actually have two spec helpers,gitlabhq/qa/spec/spec_helper.rb
andgitlabhq/spec/spec_helper.rb
.And they do use
:trigger_inclusion
:in their specs.
We use it, too.
rspec-expectations
:Preliminary conclusion: those popular Ruby projects that use RSpec who configured
shared_context_metadata_behavior
to:apply_to_host_groups
did this blindlessly and never used it.Semantic
We have two ways of inclusing shared groups.
include_context
/include_examples
andit_behaves_like
. The latter creates a nested group.It doesn't make much sense to apply metadata that is defined for an implicitly created nested group.
On the other hand, just like with several
let
s defined in different included contexts, metadata, if applied from different included contexts, has a chance to override one another, and we don't print a warning for this case, leaving space for confusion.If we happen to remove
:trigger_inclusion
, what would we recommend to replace it? E.g. for globally-defined shared groups:For globally-defined shared groups this works:
However, why is it
include_context
?Well, we only have
include_context
on ourConfiguration
object. There's notinclude_examples
orit_behaves_like
there.More common and contrived usage:
But, what to promise in return for locally-defined shared groups?
Sometimes, it's quite unweildy to call
include_context
/it_behaves_like
, and implicit inclusion via matching metadata is useful to make things dry. At a cost of a little magic. Which RSpec metadata is all about anyway.Unpopular opinion
No doubt that this option has solved the issue with the inclusion of shared examples defined in a completely unrelated scope.
However, was there a good reason to "apply metadata to host group"? Is it used? Is it useful? Isn't it confusing?
Proposal
I suggest:
shared_context_metadata_behavior
option along with its default:trigger_inclusion
value... release 4.0
:trigger_inclusion
as the default:apply_to_host_groups
If we keep
:trigger_inclusion
the default, the behaviour won't change for the majority. Less tickets.Doubts
It may require a significant overhaul to fix the inclusion, up to the point where it makes it barely possible.
I still hope the reality won't shatter my youthful overly-optimistic dreams, and it's doable.
The text was updated successfully, but these errors were encountered: