module RSpec::Core::MetadataFilter

Contains metadata filtering logic. This has been extracted from the metadata classes because it operates ON a metadata hash but does not manage any of the state in the hash. We're moving towards having metadata be a raw hash (not a custom subclass), so externalizing this filtering logic helps us move in that direction.

Public Class Methods

apply?(predicate, filters, metadata) click to toggle source

@private

# File lib/rspec/core/metadata_filter.rb, line 11
def apply?(predicate, filters, metadata)
  filters.__send__(predicate) { |k, v| filter_applies?(k, v, metadata) }
end
filter_applies?(key, value, metadata) click to toggle source

@private

# File lib/rspec/core/metadata_filter.rb, line 16
def filter_applies?(key, value, metadata)
  silence_metadata_example_group_deprecations do
    return filter_applies_to_any_value?(key, value, metadata) if Array === metadata[key] && !(Proc === value)
    return location_filter_applies?(value, metadata)          if key == :locations
    return filters_apply?(key, value, metadata)               if Hash === value

    return false unless metadata.key?(key)

    case value
    when Regexp
      metadata[key] =~ value
    when Proc
      case value.arity
      when 0 then value.call
      when 2 then value.call(metadata[key], metadata)
      else value.call(metadata[key])
      end
    else
      metadata[key].to_s == value.to_s
    end
  end
end

Private Class Methods

example_group_declaration_lines(locations, metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 59
def example_group_declaration_lines(locations, metadata)
  FlatMap.flat_map(Metadata.ascend(metadata)) do |meta|
    locations[meta[:absolute_file_path]]
  end.uniq
end
filter_applies_to_any_value?(key, value, metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 41
def filter_applies_to_any_value?(key, value, metadata)
  metadata[key].any? { |v| filter_applies?(key, v,  key => value) }
end
filters_apply?(key, value, metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 65
def filters_apply?(key, value, metadata)
  subhash = metadata[key]
  return false unless Hash === subhash || HashImitatable === subhash
  value.all? { |k, v| filter_applies?(k, v, subhash) }
end
line_number_filter_applies?(line_numbers, metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 50
def line_number_filter_applies?(line_numbers, metadata)
  preceding_declaration_lines = line_numbers.map { |n| RSpec.world.preceding_declaration_line(n) }
  !(relevant_line_numbers(metadata) & preceding_declaration_lines).empty?
end
location_filter_applies?(locations, metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 45
def location_filter_applies?(locations, metadata)
  line_numbers = example_group_declaration_lines(locations, metadata)
  line_numbers.empty? || line_number_filter_applies?(line_numbers, metadata)
end
relevant_line_numbers(metadata) click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 55
def relevant_line_numbers(metadata)
  Metadata.ascend(metadata).map { |meta| meta[:line_number] }
end
silence_metadata_example_group_deprecations() { || ... } click to toggle source
# File lib/rspec/core/metadata_filter.rb, line 71
def silence_metadata_example_group_deprecations
  RSpec.thread_local_metadata[:silence_metadata_example_group_deprecations] = true
  yield
ensure
  RSpec.thread_local_metadata.delete(:silence_metadata_example_group_deprecations)
end