Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

CLI tags override their inverses in file options and RSpec.configure

Fixes #369.
  • Loading branch information...
commit 602c23bc4066c9455f7342061cb8cbe199aa83a2 1 parent b563e7d
@dchelimsky dchelimsky authored
View
47 lib/rspec/core/configuration.rb
@@ -14,6 +14,19 @@ def self.define_predicate_for(*names)
# @api private
#
+ # Used internally to have higher priority exclusion filters
+ def self.reconcile_opposing_filters(local, authoritative, filter, opposite_filter)
+ if local[filter] && authoritative[opposite_filter]
+ local[filter].each_pair do |key, value|
+ if authoritative[opposite_filter][key] == value
+ local[filter].delete(key)
+ end
+ end
+ end
+ end
+
+ # @api private
+ #
# Invoked by the `add_setting` instance method. Use that method on a
# `Configuration` instance rather than this class method.
def self.add_setting(name, opts={})
@@ -83,13 +96,14 @@ def initialize
@failure_exit_code = 1
@backtrace_clean_patterns = DEFAULT_BACKTRACE_PATTERNS.dup
@default_path = 'spec'
+ @inclusion_filter = {}
@exclusion_filter = DEFAULT_EXCLUSION_FILTERS.dup
+ @preferred_options = {}
@seed = srand % 0xFFFF
- @dominant_options = {}
end
def force(hash)
- @dominant_options.merge!(hash)
+ @preferred_options.merge!(hash)
end
def reset
@@ -453,9 +467,9 @@ def filter_run_including(*args)
if already_set_standalone_filter?
warn_already_set_standalone_filter(filter)
elsif contains_standalone_filter?(filter)
- inclusion_filter.replace(filter)
+ @inclusion_filter.replace(filter)
else
- inclusion_filter.merge!(filter)
+ @inclusion_filter.merge!(filter)
end
end
@@ -465,7 +479,7 @@ def filter_run_including(*args)
# want any inclusion filter at all.
def inclusion_filter=(filter)
filter = build_metadata_hash_from([filter])
- filter.empty? ? inclusion_filter.clear : inclusion_filter.replace(filter)
+ filter.empty? ? @inclusion_filter.clear : @inclusion_filter.replace(filter)
end
alias_method :filter=, :inclusion_filter=
@@ -473,7 +487,7 @@ def inclusion_filter=(filter)
# Returns the `inclusion_filter`. If none has been set, returns an empty
# hash.
def inclusion_filter
- @inclusion_filter ||= {}
+ value_for(:inclusion_filter, @inclusion_filter) || {}
end
alias_method :filter, :inclusion_filter
@@ -489,20 +503,20 @@ def inclusion_filter
# # with treat_symbols_as_metadata_keys_with_true_values = true
# filter_run_excluding :foo # results in {:foo => true}
def filter_run_excluding(*args)
- exclusion_filter.merge!(build_metadata_hash_from(args))
+ @exclusion_filter.merge!(build_metadata_hash_from(args))
end
# Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't
# want any exclusion filter at all.
def exclusion_filter=(filter)
filter = build_metadata_hash_from([filter])
- filter.empty? ? exclusion_filter.clear : exclusion_filter.replace(filter)
+ filter.empty? ? @exclusion_filter.clear : @exclusion_filter.replace(filter)
end
# Returns the `exclusion_filter`. If none has been set, returns an empty
# hash.
def exclusion_filter
- @exclusion_filter ||= {}
+ value_for(:exclusion_filter, @exclusion_filter) || {}
end
STANDALONE_FILTERS = [:line_numbers, :full_description]
@@ -578,17 +592,20 @@ def order=(type)
private
def value_for(key, default=nil)
- # TODO - not sure about this name, but that's partially due to the need
- # for a default value. Once we align the CLI options with the
- # RSpec.configure options we can glean the default from the key, then
- # this name makes more sense.
- @dominant_options.has_key?(key) ? @dominant_options[key] : default
+ if [:inclusion_filter, :exclusion_filter].any? {|k| key == k}
+ local = { :inclusion_filter => @inclusion_filter, :exclusion_filter => @exclusion_filter }
+ Configuration.reconcile_opposing_filters(local, @preferred_options, :inclusion_filter, :exclusion_filter)
+ Configuration.reconcile_opposing_filters(local, @preferred_options, :exclusion_filter, :inclusion_filter)
+ @preferred_options.has_key?(key) ? default.merge(@preferred_options[key]) : default
+ else
+ @preferred_options.has_key?(key) ? @preferred_options[key] : default
+ end
end
def add_location(file_path, line_numbers)
# filter_locations is a hash of expanded paths to arrays of line
# numbers to match against.
- filter_locations = ((self.filter || {})[:locations] ||= {})
+ filter_locations = @inclusion_filter[:locations] ||= {}
(filter_locations[File.expand_path(file_path)] ||= []).push(*line_numbers)
filter_run(:locations => filter_locations)
end
View
27 lib/rspec/core/configuration_options.rb
@@ -10,29 +10,28 @@ def initialize(args)
end
def configure(config)
- formatters = options.delete(:formatters)
- inclusion_filter = options.delete(:inclusion_filter)
- exclusion_filter = options.delete(:exclusion_filter)
+ formatters = options.delete(:formatters)
+
+ config.line_numbers = line_numbers if line_numbers = options.delete(:line_numbers)
+ config.full_description = full_description if full_description = options.delete(:full_description)
order(options.keys, :libs, :requires, :default_path, :pattern).each do |key|
# temp to get through refactoring - eventually all options will be
# set using force
- if key == :color
- config.force :color => options[key]
+ if [:color, :inclusion_filter, :exclusion_filter].include? key
+ config.force key => options[key]
else
config.send("#{key}=", options[key]) if config.respond_to?("#{key}=")
end
end
formatters.each {|pair| config.add_formatter(*pair) } if formatters
- config.filter_run_including inclusion_filter if inclusion_filter
- config.filter_run_excluding exclusion_filter if exclusion_filter
end
def parse_options
@options ||= (file_options << command_line_options << env_options).inject do |merged, pending|
- resolve_opposite_filters(merged, pending, :inclusion_filter, :exclusion_filter)
- resolve_opposite_filters(merged, pending, :exclusion_filter, :inclusion_filter)
+ Configuration.reconcile_opposing_filters(merged, pending, :inclusion_filter, :exclusion_filter)
+ Configuration.reconcile_opposing_filters(merged, pending, :exclusion_filter, :inclusion_filter)
merged.merge(pending)
end
end
@@ -43,16 +42,6 @@ def drb_argv
private
- def resolve_opposite_filters(current,pending,filter,opposite_filter)
- if current[filter] && pending[opposite_filter]
- current[filter].each_pair do |key, value|
- if pending[opposite_filter][key] == value
- current[filter].delete(key)
- end
- end
- end
- end
-
def order(keys, *ordered)
ordered.reverse.each do |key|
keys.unshift(key) if keys.delete(key)
View
1  spec/rspec/core/command_line_spec.rb
@@ -95,6 +95,7 @@ def config_options(argv=[])
# this is necessary to ensure that color works correctly on windows
config.should_receive(:error_stream=).ordered
config.should_receive(:output_stream=).ordered
+ config.should_receive(:force).with(:exclusion_filter => anything).ordered
config.should_receive(:force).with(:color => true).ordered
command_line.run(err, out) rescue nil
end
View
28 spec/rspec/core/configuration_options_spec.rb
@@ -61,6 +61,20 @@
config.should_receive(:force).with(:color => true)
opts.configure(config)
end
+
+ it "forces inclusion_filter" do
+ opts = config_options_object(*%w[--tag foo:bar])
+ config = RSpec::Core::Configuration.new
+ config.should_receive(:force).with(:inclusion_filter => {:foo => 'bar'})
+ opts.configure(config)
+ end
+
+ it "forces exclusion_filter" do
+ opts = config_options_object(*%w[--tag ~foo:bar])
+ config = RSpec::Core::Configuration.new
+ config.should_receive(:force).with(:exclusion_filter => {:foo => 'bar'})
+ opts.configure(config)
+ end
end
describe "-c, --color, and --colour" do
@@ -279,6 +293,20 @@
options[:drb].should be_true
end
+ it "merges positive tags" do
+ pending
+ File.open("./.rspec", "w") {|f| f << "--tag foo:bar"}
+ parse_options("--tag", "baz:bam")[:inclusion_filter].
+ should eq({:foo => 'bar', :baz => 'bam'})
+ end
+
+ it "merges negative tags" do
+ pending
+ File.open("./.rspec", "w") {|f| f << "--tag ~foo:bar"}
+ parse_options("--tag", "~baz:bam")[:exclusion_filter].
+ should eq({:foo => 'bar', :baz => 'bam'})
+ end
+
it "prefers SPEC_OPTS over CLI" do
ENV["SPEC_OPTS"] = "--format spec_opts"
parse_options("--format", "cli")[:formatters].should eq([['spec_opts']])
View
13 spec/rspec/core/configuration_spec.rb
@@ -618,6 +618,12 @@ def metadata_hash(*args)
config.inclusion_filter[:bar].should be(false)
end
+ it "gets overrided by forced options" do
+ config.force :exclusion_filter => { :foo => true }
+ config.filter_run_including :foo => true
+ config.inclusion_filter.should eq({})
+ end
+
it "warns if :line_numbers is already a filter" do
config.filter_run_including :line_numbers => [100]
config.should_receive(:warn).with(
@@ -663,6 +669,13 @@ def metadata_hash(*args)
config.exclusion_filter[:foo].should be(true)
config.exclusion_filter[:bar].should be(false)
end
+
+ it "gets overrided by forced options" do
+ config.exclusion_filter.clear
+ config.force :inclusion_filter => { :foo => true }
+ config.filter_run_excluding :foo => true
+ config.exclusion_filter.should eq({})
+ end
end
describe "#inclusion_filter" do
View
1  spec/spec_helper.rb
@@ -77,6 +77,7 @@ def in_editor?
c.treat_symbols_as_metadata_keys_with_true_values = true
c.color = !in_editor?
c.filter_run :focus
+ c.filter_run :foo
c.run_all_when_everything_filtered = true
c.filter_run_excluding :ruby => lambda {|version|
case version.to_s
Please sign in to comment.
Something went wrong with that request. Please try again.