Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Don't process filters when the metadata doesn't even have the key.

This allows us to simplify the filter_applies? method on metadata, and
gives us a small performance boost by not evaluating procs that would
always return false.

- Closes #556.
  • Loading branch information...
commit 155e200a3501273a6b7e1de317eb7298ff9cdfba 1 parent c6dc90b
David Chelimsky dchelimsky authored
40 lib/rspec/core/configuration.rb
View
@@ -534,10 +534,26 @@ def alias_it_should_behave_like_to(new_name, report_label = '')
# or config files (e.g. `.rspec`).
#
# @example
- # filter_run_including :x => 'y'
+ # # given this declaration
+ # describe "something", :foo => 'bar' do
+ # # ...
+ # end
+ #
+ # # any of the following will include that group
+ # config.filter_run_including :foo => 'bar'
+ # config.filter_run_including :foo => /^ba/
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
+ #
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
+ # config.filter_run_including :foo => lambda {|v| v == 'bar'}
+ #
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
+ # # and the metadata itself e.g.
+ # config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
#
# # with treat_symbols_as_metadata_keys_with_true_values = true
- # filter_run_including :foo # results in {:foo => true}
+ # filter_run_including :foo # same as filter_run_including :foo => true
def filter_run_including(*args)
filter_manager.include_with_low_priority build_metadata_hash_from(args)
end
@@ -576,10 +592,26 @@ def inclusion_filter
# or config files (e.g. `.rspec`).
#
# @example
- # filter_run_excluding :x => 'y'
+ # # given this declaration
+ # describe "something", :foo => 'bar' do
+ # # ...
+ # end
+ #
+ # # any of the following will exclude that group
+ # config.filter_run_excluding :foo => 'bar'
+ # config.filter_run_excluding :foo => /^ba/
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
+ #
+ # # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
+ # config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
+ #
+ # # given a proc with an arity of 2, the lambda is passed the value related to the key,
+ # # and the metadata itself e.g.
+ # config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
#
# # with treat_symbols_as_metadata_keys_with_true_values = true
- # filter_run_excluding :foo # results in {:foo => true}
+ # filter_run_excluding :foo # same as filter_run_excluding :foo => true
def filter_run_excluding(*args)
filter_manager.exclude_with_low_priority build_metadata_hash_from(args)
end
2  lib/rspec/core/filter_manager.rb
View
@@ -67,7 +67,7 @@ module Core
# @see Configuration#filter_run_excluding
class FilterManager
DEFAULT_EXCLUSIONS = {
- :if => lambda { |value, metadata| metadata.has_key?(:if) && !value },
+ :if => lambda { |value| !value },
:unless => lambda { |value| value }
}
15 lib/rspec/core/metadata.rb
View
@@ -174,20 +174,15 @@ def filter_applies?(key, value, metadata=self)
return metadata.location_filter_applies?(value) if key == :locations
return metadata.filters_apply?(key, value) if Hash === value
+ return false unless metadata.has_key?(key)
+
case value
when Regexp
metadata[key] =~ value
when Proc
- if value.arity == 2
- # Pass the metadata hash to allow the proc to check if it even has the key.
- # This is necessary for the implicit :if exclusion filter:
- # { } # => run the example
- # { :if => nil } # => exclude the example
- # The value of metadata[:if] is the same in these two cases but
- # they need to be treated differently.
- value.call(metadata[key], metadata)
- else
- value.call(metadata[key])
+ case value.arity
+ when 1 then value.call(metadata[key])
+ when 2 then value.call(metadata[key], metadata)
end
else
metadata[key].to_s == value.to_s
16 spec/rspec/core/configuration_spec.rb
View
@@ -713,20 +713,16 @@ def metadata_hash(*args)
end
describe "the default :if filter" do
- it "does not exclude a spec with no :if metadata" do
- config.exclusion_filter[:if].call(nil, {}).should be_false
+ it "does not exclude a spec with { :if => true } metadata" do
+ config.exclusion_filter[:if].call(true).should be_false
end
- it "does not exclude a spec with { :if => true } metadata" do
- config.exclusion_filter[:if].call(true, {:if => true}).should be_false
+ it "excludes a spec with { :if => false } metadata" do
+ config.exclusion_filter[:if].call(false).should be_true
end
- it "excludes a spec with { :if => false } metadata" do
- config.exclusion_filter[:if].call(false, {:if => false}).should be_true
- end
-
- it "excludes a spec with { :if => nil } metadata" do
- config.exclusion_filter[:if].call(false, {:if => nil}).should be_true
+ it "excludes a spec with { :if => nil } metadata" do
+ config.exclusion_filter[:if].call(nil).should be_true
end
end
7 spec/rspec/core/metadata_spec.rb
View
@@ -126,10 +126,9 @@ module Core
example_metadata.filter_applies?(:if, lambda { |v| !v }).should be_false
end
- it "passes the metadata hash as the second argument if a given proc expects 2 args" do
- passed_metadata = nil
- example_metadata.filter_applies?(:if, lambda { |v, m| passed_metadata = m })
- passed_metadata.should eq(example_metadata)
+ it "matches a proc with an arity of 2" do
+ example_metadata[:foo] = nil
+ example_metadata.filter_applies?(:foo, lambda { |v, m| m == example_metadata }).should be_true
end
context "with an Array" do
Please sign in to comment.
Something went wrong with that request. Please try again.