Skip to content

Commit

Permalink
introduce the concept of RESERVED_KEYS to metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
dchelimsky committed Mar 7, 2010
1 parent 28db011 commit e47367b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 30 deletions.
2 changes: 1 addition & 1 deletion lib/rspec/core/example_group.rb
Expand Up @@ -69,7 +69,7 @@ def self.configuration


def self.set_it_up(*args) def self.set_it_up(*args)
@configuration = args.shift @configuration = args.shift
@metadata = Rspec::Core::Metadata.process(superclass_metadata, *args) @metadata = Rspec::Core::Metadata.new(superclass_metadata).process(*args)


configuration.find_modules(self).each do |include_or_extend, mod, opts| configuration.find_modules(self).each do |include_or_extend, mod, opts|
if include_or_extend == :extend if include_or_extend == :extend
Expand Down
64 changes: 45 additions & 19 deletions lib/rspec/core/metadata.rb
Expand Up @@ -2,14 +2,6 @@ module Rspec
module Core module Core
class Metadata < Hash class Metadata < Hash


def self.process(superclass_metadata, *args)
new(superclass_metadata) do |metadata|
metadata.process(*args)
end
end

attr_reader :superclass_metadata

def initialize(superclass_metadata=nil) def initialize(superclass_metadata=nil)
@superclass_metadata = superclass_metadata @superclass_metadata = superclass_metadata
update(@superclass_metadata) if @superclass_metadata update(@superclass_metadata) if @superclass_metadata
Expand All @@ -18,22 +10,52 @@ def initialize(superclass_metadata=nil)
yield self if block_given? yield self if block_given?
end end


# TODO - need to add :caller to this list, but we're using
# it for our own specs
RESERVED_KEYS = [
:behaviour,
:description,
:example_group,
:execution_result,
:file_path,
:full_description,
:line_number,
:location
]

def process(*args) def process(*args)
extra_metadata = args.last.is_a?(Hash) ? args.pop : {} user_metadata = args.last.is_a?(Hash) ? args.pop : {}
extra_metadata.delete(:example_group) # Remove it when present to prevent it clobbering the one we setup RESERVED_KEYS.each do |key|
extra_metadata.delete(:behaviour) # Remove it when present to prevent it clobbering the one we setup if user_metadata.keys.include?(key)
raise <<-EOM
#{"*"*50}
:#{key} is not allowed
Rspec reserves some hash keys for its own internal use,
including :#{key}, which is used on:
#{caller(0)[1]}.
Here are all of Rspec's reserved hash keys:
#{RESERVED_KEYS.join("\n ")}
#{"*"*50}
EOM
raise ":#{key} is not allowed"
end
end


self[:example_group][:describes] = described_class_from(args) self[:example_group][:describes] = described_class_from(args)
self[:example_group][:description] = description_from(args) self[:example_group][:description] = description_from(args)
self[:example_group][:full_description] = full_description_from(args) self[:example_group][:full_description] = full_description_from(args)


self[:example_group][:block] = extra_metadata.delete(:example_group_block) self[:example_group][:block] = user_metadata.delete(:example_group_block)
self[:example_group][:caller] = extra_metadata.delete(:caller) || caller(1) self[:example_group][:caller] = user_metadata.delete(:caller) || caller(1)
self[:example_group][:file_path] = file_path_from(self[:example_group], extra_metadata.delete(:file_path)) self[:example_group][:file_path] = file_path_from(self[:example_group], user_metadata.delete(:file_path))
self[:example_group][:line_number] = line_number_from(self[:example_group], extra_metadata.delete(:line_number)) self[:example_group][:line_number] = line_number_from(self[:example_group], user_metadata.delete(:line_number))
self[:example_group][:location] = location_from(self[:example_group]) self[:example_group][:location] = location_from(self[:example_group])


update(extra_metadata) update(user_metadata)
end end


def for_example(description, options) def for_example(description, options)
Expand Down Expand Up @@ -81,12 +103,16 @@ def all_apply?(filters)


private private


def superclass_metadata
@superclass_metadata ||= { :example_group => {} }
end

def description_from(args) def description_from(args)
@build_description ||= args.map{|a| a.to_s.strip}.join(" ") @description_from_args ||= args.map{|a| a.to_s.strip}.join(" ")
end end


def full_description_from(args) def full_description_from(args)
if superclass_metadata && superclass_metadata[:example_group][:full_description] if superclass_metadata[:example_group][:full_description]
"#{superclass_metadata[:example_group][:full_description]} #{description_from(args)}" "#{superclass_metadata[:example_group][:full_description]} #{description_from(args)}"
else else
description_from(args) description_from(args)
Expand All @@ -95,7 +121,7 @@ def full_description_from(args)


def described_class_from(args) def described_class_from(args)
if args.first.is_a?(String) if args.first.is_a?(String)
self.superclass_metadata && self.superclass_metadata[:example_group][:describes] superclass_metadata[:example_group][:describes]
else else
args.first args.first
end end
Expand Down
41 changes: 31 additions & 10 deletions spec/rspec/core/metadata_spec.rb
Expand Up @@ -4,6 +4,37 @@ module Rspec
module Core module Core
describe Metadata do describe Metadata do


describe "#process" do
Metadata::RESERVED_KEYS.each do |key|
it "prohibits :#{key} as a hash key" do
m = Metadata.new
expect do
m.process('group', key => {})
end.to raise_error(/:#{key} is not allowed/)
end
end
end

describe "[:description]" do
it "just has the example description" do
m = Metadata.new
m.process('group')

m = m.for_example("example", {})
m[:description].should == "example"
end
end

describe "[:full_description]" do
it "concats the example group name and description" do
m = Metadata.new
m.process('group')

m = m.for_example("example", {})
m[:full_description].should == "group example"
end
end

describe "[:example_group][:description]" do describe "[:example_group][:description]" do
context "with a string" do context "with a string" do
it "provides the submitted description" do it "provides the submitted description" do
Expand Down Expand Up @@ -33,16 +64,6 @@ module Core
end end
end end


describe "[:full_description]" do
it "concats the example group name and description" do
m = Metadata.new
m.process('group')

m = m.for_example("example", {})
m[:full_description].should == "group example"
end
end

describe "[:example_group][:full_description]" do describe "[:example_group][:full_description]" do
it "concats the nested example group descriptions" do it "concats the nested example group descriptions" do
parent = Metadata.new parent = Metadata.new
Expand Down

0 comments on commit e47367b

Please sign in to comment.