123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Core::ConfigurationOptions

Relationships & Source Files
Inherits: Object
Defined in: rspec-core/lib/rspec/core/configuration_options.rb

Overview

Responsible for utilizing externally provided configuration options, whether via the command line, .rspec, ~/.rspec, $XDG_CONFIG_HOME/rspec/options, .rspec-local or a custom options file.

Constant Summary

  • OPTIONS_ORDER =
    # File 'rspec-core/lib/rspec/core/configuration_options.rb', line 77
    [
      # It's important to set this before anything that might issue a
      # deprecation (or otherwise access the reporter).
      :deprecation_stream,
    
      # In order for `RSpec.configuration.dry_run?` to return `true` during
      # processing the `requires` option, it must be parsed before it.
      :dry_run,
    
      # load paths depend on nothing, but must be set before `requires`
      # to support load-path-relative requires.
      :libs,
    
      # `files_or_directories_to_run` uses `default_path` so it must be
      # set before it.
      :default_path, :only_failures,
    
      # These must be set before `requires` to support checking
      # `config.files_to_run` from within `spec_helper.rb` when a
      # `-rspec_helper` option is used.
      :files_or_directories_to_run, :pattern, :exclude_pattern,
    
      # Necessary so that the `--seed` option is applied before requires,
      # in case required files do something with the provided seed.
      # (such as seed global randomization with it).
      :order,
    
      # In general, we want to require the specified files as early as
      # possible. The `--require` option is specifically intended to allow
      # early requires. For later requires, they can just put the require in
      # their spec files, but `--require` provides a unique opportunity for
      # users to instruct RSpec to load an extension file early for maximum
      # flexibility.
      :requires
    ]
  • UNFORCED_OPTIONS =
    # File 'rspec-core/lib/rspec/core/configuration_options.rb', line 59
    Set.new([
      :requires, :profile, :drb, :libs, :files_or_directories_to_run,
      :full_description, :full_backtrace, :tty
    ])
  • UNPROCESSABLE_OPTIONS =
    # File 'rspec-core/lib/rspec/core/configuration_options.rb', line 64
    Set.new([:formatters])

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(args) ⇒ ConfigurationOptions

Parameters:

  • args (Array<String>)

    command line arguments

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 12

def initialize(args)
  @args = args.dup
  organize_options
end

Instance Attribute Details

#argsArray<String> (readonly)

Returns:

  • (Array<String>)

    the original command-line arguments

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 40

attr_reader :args

#optionsHash (readonly)

Returns:

  • (Hash)

    the final merged options, drawn from all external sources

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 37

attr_reader :options

Instance Method Details

#args_from_options_file(path) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 173

def args_from_options_file(path)
  return [] unless path && File.exist?(path)
  config_string = options_file_as_erb_string(path)
  config_lines = config_string.split(/\n+/).reject { |s| s =~ /\A\s*#/ }
  FlatMap.flat_map(config_lines, &:shellsplit)
end

#command_line_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 142

def command_line_options
  @command_line_options ||= Parser.parse(@args)
end

#configure(config)

Updates the provided Configuration instance based on the provided external configuration options.

Parameters:

  • config (Configuration)

    the configuration instance to update

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 21

def configure(config)
  process_options_into config
  configure_filter_manager config.filter_manager
  load_formatters_into config
end

#configure_filter_manager(filter_manager)

This method is for internal use only.

Updates the provided FilterManager based on the filter options.

Parameters:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 30

def configure_filter_manager(filter_manager)
  @filter_manager_options.each do |command, value|
    filter_manager.__send__ command, value
  end
end

#custom_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 146

def custom_options
  options_from(custom_options_file)
end

#custom_options_file (private)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 190

def custom_options_file
  command_line_options[:custom_options_file]
end

#env_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 133

def env_options
  return {} unless ENV['SPEC_OPTS']

  parse_args_ignoring_files_or_dirs_to_run(
    Shellwords.split(ENV["SPEC_OPTS"]),
    "ENV['SPEC_OPTS']"
  )
end

#file_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 125

def file_options
  if custom_options_file
    [custom_options]
  else
    [global_options, project_options, local_options]
  end
end

#force?(key) ⇒ Boolean (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 66

def force?(key)
  !UNFORCED_OPTIONS.include?(key)
end

#global_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 158

def global_options
  @global_options ||= options_from(global_options_file)
end

#global_options_file (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 202

def global_options_file
  xdg_options_file_if_exists || home_options_file_path
end

#home_options_file_path (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 213

def home_options_file_path
  File.join(File.expand_path("~"), ".rspec")
rescue ArgumentError
  # :nocov:
  RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
  nil
  # :nocov:
end

#load_formatters_into(config) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 121

def load_formatters_into(config)
  options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters]
end

#local_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 150

def local_options
  @local_options ||= options_from(local_options_file)
end

#local_options_file (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 198

def local_options_file
  "./.rspec-local"
end

#options_file_as_erb_string(path) (private)

:nocov:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 181

def options_file_as_erb_string(path)
  if RUBY_VERSION >= '2.6'
    ERB.new(File.read(path), :trim_mode => '-').result(binding)
  else
    ERB.new(File.read(path), nil, '-').result(binding)
  end
end

#options_from(path) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 162

def options_from(path)
  args = args_from_options_file(path)
  parse_args_ignoring_files_or_dirs_to_run(args, path)
end

#order(keys) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 70

def order(keys)
  OPTIONS_ORDER.reverse_each do |key|
    keys.unshift(key) if keys.delete(key)
  end
  keys
end

#organize_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 44

def organize_options
  @filter_manager_options = []

  @options = (file_options << command_line_options << env_options).each do |opts|
    @filter_manager_options << [:include, opts.delete(:inclusion_filter)] if opts.key?(:inclusion_filter)
    @filter_manager_options << [:exclude, opts.delete(:exclusion_filter)] if opts.key?(:exclusion_filter)
  end

  @options = @options.inject(:libs => [], :requires => []) do |hash, opts|
    hash.merge(opts) do |key, oldval, newval|
      [:libs, :requires].include?(key) ? oldval + newval : newval
    end
  end
end

#parse_args_ignoring_files_or_dirs_to_run(args, source) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 167

def parse_args_ignoring_files_or_dirs_to_run(args, source)
  options = Parser.parse(args, source)
  options.delete(:files_or_directories_to_run)
  options
end

#process_options_into(config) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 113

def process_options_into(config)
  opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k }

  order(opts.keys).each do |key|
    force?(key) ? config.force(key => opts[key]) : config.__send__("#{key}=", opts[key])
  end
end

#project_options (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 154

def project_options
  @project_options ||= options_from(project_options_file)
end

#project_options_file (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 194

def project_options_file
  "./.rspec"
end

#resolve_xdg_config_home (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 229

def resolve_xdg_config_home
  File.expand_path(ENV.fetch("XDG_CONFIG_HOME", "~/.config"))
rescue ArgumentError
  # :nocov:
  # On Ruby 2.4, `File.expand("~")` works even if `ENV['HOME']` is not set.
  # But on earlier versions, it fails.
  nil
  # :nocov:
end

#xdg_options_file_if_exists (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 206

def xdg_options_file_if_exists
  path = xdg_options_file_path
  if path && File.exist?(path)
    path
  end
end

#xdg_options_file_path (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/configuration_options.rb', line 222

def xdg_options_file_path
  xdg_config_home = resolve_xdg_config_home
  if xdg_config_home
    File.join(xdg_config_home, "rspec", "options")
  end
end