Permalink
Browse files

nested group returns own described class if parent doesn't have one

  • Loading branch information...
1 parent 25b1ff5 commit 2336a7f550f855dc2fd576f89c9ae216e78dab4e @dchelimsky dchelimsky committed Oct 3, 2011
Showing with 55 additions and 31 deletions.
  1. +40 −14 lib/rspec/core/metadata.rb
  2. +15 −17 spec/rspec/core/metadata_spec.rb
View
@@ -44,21 +44,11 @@ def first_caller_from_outside_rspec
end
def described_class_for(m)
- while m.has_key?(:example_group)
- return m[:example_group][:describes] if m[:example_group].has_key?(:describes)
- m = m[:example_group]
- end
- candidate = m[:description_args].first
- String === candidate || Symbol === candidate ? nil : candidate
+ m[:example_group][:describes]
end
def full_description_for(m)
- parts = [m[:description_args]]
- while m.has_key?(:example_group)
- m = m[:example_group]
- parts.unshift m[:description_args]
- end
- build_description_from(*parts.flatten)
+ build_description_from(m[:example_group][:full_description], *m[:description_args])
end
def build_description_from(*parts)
@@ -68,12 +58,48 @@ def build_description_from(*parts)
end
end
+ module GroupMetadataHash
+ include MetadataHash
+
+ def described_class_for(*)
+ ancestors.each do |g|
+ return g[:describes] if g.has_key?(:describes)
+ end
+
+ ancestors.reverse.each do |g|
+ candidate = g[:description_args].first
+ return candidate unless String === candidate || Symbol === candidate
+ end
+
+ nil
+ end
+
+ def full_description_for(*)
+ build_description_from(*ancestors.reverse.map do |a|
+ a.has_key?(:full_description) ? a[:full_description] : a[:description_args]
+ end.flatten)
+ end
+
+ private
+
+ def ancestors
+ @ancestors ||= begin
+ groups = [group = self]
+ while group.has_key?(:example_group)
+ groups << group[:example_group]
+ group = group[:example_group]
+ end
+ groups
+ end
+ end
+ end
+
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(MetadataHash))
+ store(:example_group, {:example_group => parent_group_metadata[:example_group]}.extend(GroupMetadataHash))
else
- store(:example_group, {}.extend(MetadataHash))
+ store(:example_group, {}.extend(GroupMetadataHash))
end
yield self if block_given?
@@ -186,7 +186,6 @@ module Core
m = Metadata.new
m.process('group')
- m = m.for_example("example", {})
m[:example_group][:describes].should be_nil
end
end
@@ -196,7 +195,6 @@ module Core
m = Metadata.new
m.process(:group)
- m = m.for_example("example", {})
m[:example_group][:describes].should be_nil
end
end
@@ -206,45 +204,45 @@ module Core
m = Metadata.new
m.process(String)
- m = m.for_example("example", {})
m[:example_group][:describes].should be(String)
end
end
- context "with describes from a parent group metadata" do
+ context "in a nested group" do
it "returns the parent group's described class" do
sm = Metadata.new
sm.process(String)
m = Metadata.new(sm)
m.process(Array)
- m = m.for_example("example", {})
m[:example_group][:describes].should be(String)
end
+ it "returns own described class if parent doesn't have one" do
+ sm = Metadata.new
+ sm.process("foo")
+
+ m = Metadata.new(sm)
+ m.process(Array)
+
+ m[:example_group][:describes].should be(Array)
+ end
+
it "can override a parent group's described class" do
parent = Metadata.new
parent.process(String)
child = Metadata.new(parent)
- child.process(Hash)
+ child.process(Fixnum)
child[:example_group][:describes] = Hash
grandchild = Metadata.new(child)
grandchild.process(Array)
- grandchild.for_example("example", {}).tap do |e|
- e[:example_group][:describes].should be(Hash)
- end
-
- child.for_example("example", {}).tap do |e|
- e[:example_group][:describes].should be(Hash)
- end
-
- parent.for_example("example", {}).tap do |e|
- e[:example_group][:describes].should be(String)
- end
+ grandchild[:example_group][:describes].should be(Hash)
+ child[:example_group][:describes].should be(Hash)
+ parent[:example_group][:describes].should be(String)
end
end
end

0 comments on commit 2336a7f

Please sign in to comment.