class RSpec::Core::Metadata
@see Configuration#filter_run_excluding
@see Configuration#filter_run_including
@see FilterManager
@see ExampleGroup.metadata
@see Example#metadata
run (e.g. ‘filter_run_including`, `filter_run_excluding`, etc).
the command line, or several methods on `Configuration` used to filter a
then be used to select which examples are run using the `–tag` option on
`:slow => true` is stored in the Metadata owned by the example. These can
`:type => :ui` is stored in the Metadata owned by the example group, and
end
end
# …
it “does something”, :slow => true do
describe Something, :type => :ui do
user-supplied metadata, e.g.
In addition to metadata that is used internally, this also stores
associated with keys that may or may not be used by any example or group.
Metadata, which is Hash extended to support lazy evaluation of values
Each ExampleGroup class and Example instance owns an instance of
def self.relative_path(line)
def self.relative_path(line) line = line.sub(File.expand_path("."), ".") line = line.sub(/\A([^:]+:\d+)$/, '\\1') return nil if line == '-e:1' line rescue SecurityError nil end
def all_apply?(filters)
- Private: -
def all_apply?(filters) filters.all? {|k,v| filter_applies?(k,v)} end
def any_apply?(filters)
- Private: -
def any_apply?(filters) filters.any? {|k,v| filter_applies?(k,v)} end
def configure_for_example(description, user_metadata)
def configure_for_example(description, user_metadata) store(:description_args, [description]) store(:caller, user_metadata.delete(:caller) || caller) update(user_metadata) end
def ensure_valid_keys(user_metadata)
def ensure_valid_keys(user_metadata) RESERVED_KEYS.each do |key| if user_metadata.has_key?(key) raise <<-EOM #{"*"*50} } is not allowed reserves some hash keys for its own internal use, ing :#{key}, which is used on: #{caller(0)[4]}. re all of RSpec's reserved hash keys: #{RESERVED_KEYS.join("\n ")} #{"*"*50} EOM end end end
def example_group_declaration_line(locations)
def example_group_declaration_line(locations) locations[File.expand_path(self[:example_group][:file_path])] if self[:example_group] end
def filter_applies?(key, value, metadata=self)
- Private: -
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
def filter_applies_to_any_value?(key, value)
- Private: -
def filter_applies_to_any_value?(key, value) self[key].any? {|v| filter_applies?(key, v, {key => value})} end
def filters_apply?(key, value)
- Private: -
def filters_apply?(key, value) value.all? {|k, v| filter_applies?(k, v, self[key])} end
def for_example(description, user_metadata)
- Private: -
def for_example(description, user_metadata) dup.extend(ExampleMetadataHash).configure_for_example(description, user_metadata) end
def initialize(parent_group_metadata=nil)
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
def line_number_filter_applies?(line_numbers)
- Private: -
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
def location_filter_applies?(locations)
- Private: -
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
def process(*args)
- Private: -
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
def relevant_line_numbers(metadata=self)
TODO - make this a method on metadata - the problem is
def relevant_line_numbers(metadata=self) [metadata[:line_number]] + (metadata[:example_group] ? relevant_line_numbers(metadata[:example_group]) : []) end