module Rspec module Core class Configuration # Control what examples are run by filtering attr_accessor :filter # Control what examples are not run by filtering attr_accessor :exclusion_filter # Run all examples if the run is filtered, and no examples were found. attr_writer :run_all_when_everything_filtered attr_reader :options def initialize @run_all_when_everything_filtered = false @hooks = { :before => { :each => [], :all => [], :suite => [] }, :after => { :each => [], :all => [], :suite => [] } } @include_or_extend_modules = [] @filter, @exclusion_filter = nil, nil @options = default_options end def default_options { :color_enabled => false, :mock_framework => nil, :use_transactional_examples => true, :profile_examples => false, :files_to_run => [], :filename_pattern => '**/*_spec.rb', :formatter_class => Rspec::Core::Formatters::ProgressFormatter, :backtrace_clean_patterns => [/\/lib\/ruby\//, /bin\/rcov:/, /vendor\/rails/, /bin\/rspec/, /bin\/spec/, /lib\/rspec\/(core|expectations|matchers|mocks)/] } end def cleaned_from_backtrace?(line) @options[:backtrace_clean_patterns].any? { |regex| line =~ regex } end def backtrace_clean_patterns @options[:backtrace_clean_patterns] end def mock_framework=(use_me_to_mock) @options[:mock_framework] = use_me_to_mock end def use_transactional_examples=(value) @options[:use_transactional_examples] = value end def use_transactional_examples? @options[:use_transactional_examples] end def require_mock_framework_adapter require case @options[:mock_framework].to_s when "", /rspec/i 'rspec/core/mocking/with_rspec' when /mocha/i 'rspec/core/mocking/with_mocha' when /rr/i 'rspec/core/mocking/with_rr' when /flexmock/i 'rspec/core/mocking/with_flexmock' else 'rspec/core/mocking/with_absolutely_nothing' end end def filename_pattern @options[:filename_pattern] end def filename_pattern=(new_pattern) @options[:filename_pattern] = new_pattern end def color_enabled=(on_or_off) @options[:color_enabled] = on_or_off end def full_backtrace=(bool) @options[:backtrace_clean_patterns].clear end def libs=(libs) libs.map {|lib| $LOAD_PATH.unshift lib} end def debug=(bool) return unless bool begin require 'ruby-debug' rescue LoadError raise <<-EOM #{'*'*50} You must install ruby-debug to run rspec with the --debug option. If you have ruby-debug installed as a ruby gem, then you need to either require 'rubygems' or configure the RUBYOPT environment variable with the value 'rubygems'. #{'*'*50} EOM end end def color_enabled? @options[:color_enabled] end def line_number=(line_number) filter_run :line_number => line_number.to_i end def full_description=(description) filter_run :full_description => /#{description}/ end # Enable profiling of example run - defaults to false def profile_examples @options[:profile_examples] end def profile_examples=(on_or_off) @options[:profile_examples] = on_or_off end def formatter_class @options[:formatter_class] end def formatter=(formatter_to_use) formatter_class = case formatter_to_use.to_s when 'd', 'doc', 'documentation', 's', 'n', 'spec', 'nested' Rspec::Core::Formatters::DocumentationFormatter when 'progress' Rspec::Core::Formatters::ProgressFormatter else raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?." end @options[:formatter_class] = formatter_class end def formatter @formatter ||= formatter_class.new end def files_to_run @options[:files_to_run] end def files_or_directories_to_run=(*files) @options[:files_to_run] = files.flatten.inject([]) do |result, file| if File.directory?(file) filename_pattern.split(",").each do |pattern| result += Dir["#{file}/#{pattern.strip}"] end else path, line_number = file.split(':') self.line_number = line_number if line_number result << path end result end end # E.g. alias_example_to :crazy_slow, :speed => 'crazy_slow' defines # crazy_slow as an example variant that has the crazy_slow speed option def alias_example_to(new_name, extra_options={}) Rspec::Core::ExampleGroup.alias_example_to(new_name, extra_options) end def filter_run(options={}) @filter = options unless @filter and @filter[:line_number] || @filter[:full_description] end def run_all_when_everything_filtered? @run_all_when_everything_filtered end def output $stdout end def puts(msg="") output.puts(msg) end def include(mod, options={}) @include_or_extend_modules << [:include, mod, options] end def extend(mod, options={}) @include_or_extend_modules << [:extend, mod, options] end def find_modules(group) @include_or_extend_modules.select do |include_or_extend, mod, filters| group.all_apply?(filters) end end def before(each_or_all=:each, options={}, &block) @hooks[:before][each_or_all] << [options, block] end def after(each_or_all=:each, options={}, &block) @hooks[:after][each_or_all] << [options, block] end def find_hook(hook, each_or_all, group) @hooks[hook][each_or_all].select do |filters, block| group.all_apply?(filters) end.map { |filters, block| block } end def configure_mock_framework require_mock_framework_adapter Rspec::Core::ExampleGroup.send(:include, Rspec::Core::MockFrameworkAdapter) end def require_files_to_run files_to_run.map {|f| require f } end end end end