Unify multiple-condition filtering
Created by: myronmarston
When applying metadata conditions for filltering (e.g. hooks, module inclusions, shared example group inclusion, define derived metadata, etc) we sometimes use an :all?
semantic (for hooks) and sometimes an :any?
semantic (for everything else). This is inconsistent and hard to explain to users. I don't think we ever consciously chose to make it diverge but we never sat down and thought through how we could have a unified semantic.
As part of #1796 I've thought about this quite a bit and I think it would be nice to unify the filtering. I'm leaning towards making it all?
because it allows us to support both:
RSpec.configure do |c|
# MyModule will only be included in groups with both `:foo => true` AND `:bar => true`
c.include MyModule, :foo => true, :bar => true
end
#...but if you want the `any?` semantic, just call `include` twice:
RSpec.configure do |c|
# MyModule will only be included in groups with either `:foo => true` OR `:bar => true`
c.include MyModule, :foo => true
c.include MyModule, :bar => true
end
In effect, you can think of each call to include
as adding an entry to a metadata_filter_hashes
array, and the logic winds up being:
if metadata_filter_hashes.any? do |hash|
if hash.all? { |k, v| applies?(k, v) }
do_it!
end
end
If we were to standardize on any?
semantics, I don't think there'd be any way for users to get the all?
semantic when they wanted it.
This would be a breaking change and would have to go in 4.0, unless we wanted to introduce a config option sooner. I think this would be a pretty unobtrusive change for most users (as multi-condition filtering isn't often used).
We may also want to remove the :if
and :unless
filter support, as it adds complexity for little benifit over a normal ruby if
and unless
.