class RSpec::Core::Metadata

Each ExampleGroup class and Example instance owns an instance of Metadata, which is Hash extended to support lazy evaluation of values associated with keys that may or may not be used by any example or group.

In addition to metadata that is used internally, this also stores user-supplied metadata, e.g.

describe Something, :type => :ui do
  it "does something", :slow => true do
    # ...
  end
end

`:type => :ui` is stored in the Metadata owned by the example group, and `:slow => true` is stored in the Metadata owned by the example. These can then be used to select which examples are run using the `--tag` option on the command line, or several methods on `Configuration` used to filter a run (e.g. `filter_run_including`, `filter_run_excluding`, etc).

@see RSpec::Core::Example#metadata @see RSpec::Core::ExampleGroup.metadata @see FilterManager @see RSpec::Core::Configuration#filter_run_including @see RSpec::Core::Configuration#filter_run_excluding

Constants

RESERVED_KEYS

Public Class Methods

new(parent_group_metadata=nil) { |self| ... } click to toggle source
# File lib/rspec/core/metadata.rb, line 140
def initialize(parent_group_metadata=nil)
  if parent_group_metadata
    update(parent_group_metadata)
    store(:example_group, {:example_group => parent_group_metadata[:example_group].extend(GroupMetadataHash)}.extend(GroupMetadataHash))
  else
    store(:example_group, {}.extend(GroupMetadataHash))
  end

  yield self if block_given?
end
relative_path(line) click to toggle source
# File lib/rspec/core/metadata.rb, line 29
def self.relative_path(line)
  line = line.sub(File.expand_path("."), ".")
  line = line.sub(%r\A([^:]+:\d+)$/, '\1')
  return nil if line == '-e:1'
  line
end

Public Instance Methods

all_apply?(filters) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 173
def all_apply?(filters)
  filters.all? {|k,v| filter_applies?(k,v)}
end
any_apply?(filters) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 168
def any_apply?(filters)
  filters.any? {|k,v| filter_applies?(k,v)}
end
filter_applies?(key, value, metadata=self) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 178
def filter_applies?(key, value, metadata=self)
  return metadata.filter_applies_to_any_value?(key, value) if Array === metadata[key] && !(Proc === value)
  return metadata.line_number_filter_applies?(value)       if key == :line_numbers
  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
    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
filter_applies_to_any_value?(key, value) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 206
def filter_applies_to_any_value?(key, value)
  self[key].any? {|v| filter_applies?(key, v, {key => value})}
end
filters_apply?(key, value) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 201
def filters_apply?(key, value)
  value.all? {|k, v| filter_applies?(k, v, self[key])}
end
for_example(description, user_metadata) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 163
def for_example(description, user_metadata)
  dup.extend(ExampleMetadataHash).configure_for_example(description, user_metadata)
end
line_number_filter_applies?(line_numbers) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 218
def line_number_filter_applies?(line_numbers)
  preceding_declaration_lines = line_numbers.map {|n| RSpec.world.preceding_declaration_line(n)}
  !(relevant_line_numbers & preceding_declaration_lines).empty?
end
location_filter_applies?(locations) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 211
def location_filter_applies?(locations)
  # it ignores location filters for other files
  line_number = example_group_declaration_line(locations)
  line_number ? line_number_filter_applies?(line_number) : true
end
process(*args) click to toggle source

@private

# File lib/rspec/core/metadata.rb, line 152
def process(*args)
  user_metadata = args.last.is_a?(Hash) ? args.pop : {}
  ensure_valid_keys(user_metadata)

  self[:example_group].store(:description_args, args)
  self[:example_group].store(:caller, user_metadata.delete(:caller) || caller)

  update(user_metadata)
end

Protected Instance Methods

configure_for_example(description, user_metadata) click to toggle source
# File lib/rspec/core/metadata.rb, line 225
def configure_for_example(description, user_metadata)
  store(:description_args, [description])
  store(:caller, user_metadata.delete(:caller) || caller)
  update(user_metadata)
end