Commit
- related to #528.
- Loading branch information
There are no files selected for viewing
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
|
@@ -54,14 +54,6 @@ def first_caller_from_outside_rspec | ||
self[:caller].detect {|l| l !~ /\/lib\/rspec\/core/} | self[:caller].detect {|l| l !~ /\/lib\/rspec\/core/} | ||
end | end | ||
|
|
||
def described_class | |||
self[:example_group][:described_class] | |||
end | |||
|
|||
def full_description | |||
build_description_from(self[:example_group][:full_description], *self[:description_args]) | |||
end | |||
|
|||
def build_description_from(*parts) | def build_description_from(*parts) | ||
parts.map {|p| p.to_s}.inject do |desc, p| | parts.map {|p| p.to_s}.inject do |desc, p| | ||
p =~ /^(#|::|\.)/ ? "#{desc}#{p}" : "#{desc} #{p}" | p =~ /^(#|::|\.)/ ? "#{desc}#{p}" : "#{desc} #{p}" | ||
|
@@ -73,23 +65,28 @@ def build_description_from(*parts) | ||
# lazy evaluation of some values. | # lazy evaluation of some values. | ||
module ExampleMetadataHash | module ExampleMetadataHash | ||
include MetadataHash | include MetadataHash | ||
|
|||
def described_class | |||
self[:example_group].described_class | |||
end | |||
|
|||
def full_description | |||
build_description_from(self[:example_group][:full_description], *self[:description_args]) | |||
end | |||
end | end | ||
|
|
||
# Mixed in to Metadata for an ExampleGroup (extends MetadataHash) to | # Mixed in to Metadata for an ExampleGroup (extends MetadataHash) to | ||
# support lazy evaluation of some values. | # support lazy evaluation of some values. | ||
module GroupMetadataHash | module GroupMetadataHash | ||
include MetadataHash | include MetadataHash | ||
|
|
||
private | |||
|
|||
def described_class | def described_class | ||
ancestors.each do |g| | container_stack.each do |g| | ||
# TODO remove describes | return g[:describes] if g.has_key?(:describes) | ||
return g[:describes] if g.has_key?(:describes) | |||
return g[:described_class] if g.has_key?(:described_class) | return g[:described_class] if g.has_key?(:described_class) | ||
end | end | ||
|
|
||
ancestors.reverse.each do |g| | container_stack.reverse.each do |g| | ||
candidate = g[:description_args].first | candidate = g[:description_args].first | ||
return candidate unless String === candidate || Symbol === candidate | return candidate unless String === candidate || Symbol === candidate | ||
end | end | ||
|
@@ -98,11 +95,11 @@ def described_class | ||
end | end | ||
|
|
||
def full_description | def full_description | ||
build_description_from(*ancestors.reverse.map {|a| a[:description_args]}.flatten) | build_description_from(*container_stack.reverse.map {|a| a[:description_args]}.flatten) | ||
end | end | ||
|
|
||
def ancestors | def container_stack | ||
@ancestors ||= begin | @container_stack ||= begin | ||
groups = [group = self] | groups = [group = self] | ||
while group.has_key?(:example_group) | while group.has_key?(:example_group) | ||
groups << group[:example_group] | groups << group[:example_group] | ||
|
@@ -116,7 +113,7 @@ def ancestors | ||
def initialize(parent_group_metadata=nil) | def initialize(parent_group_metadata=nil) | ||
if parent_group_metadata | if parent_group_metadata | ||
update(parent_group_metadata) | update(parent_group_metadata) | ||
store(:example_group, {:example_group => parent_group_metadata[:example_group]}.extend(GroupMetadataHash)) | store(:example_group, {:example_group => parent_group_metadata[:example_group].extend(GroupMetadataHash)}.extend(GroupMetadataHash)) | ||
else | else | ||
store(:example_group, {}.extend(GroupMetadataHash)) | store(:example_group, {}.extend(GroupMetadataHash)) | ||
end | end | ||
|
@@ -152,36 +149,48 @@ def all_apply?(filters) | ||
|
|
||
# @private | # @private | ||
def filter_applies?(key, value, metadata=self) | def filter_applies?(key, value, metadata=self) | ||
case value | case key | ||
when Hash | when :line_numbers | ||
if key == :locations | metadata.line_number_filter_applies?(value) | ||
filter_for_locations?(value, metadata) | when :locations | ||
This comment has been minimized.
Sorry, something went wrong. |
|||
else | metadata.location_filter_applies?(value) | ||
else | |||
case value | |||
when Hash | |||
value.all? { |k, v| filter_applies?(k, v, metadata[key]) } | value.all? { |k, v| filter_applies?(k, v, metadata[key]) } | ||
end | when Enumerable | ||
when Regexp | metadata[key] == value | ||
metadata[key] =~ value | when Regexp | ||
when Proc | metadata[key] =~ value | ||
if value.arity == 2 | when Proc | ||
# Pass the metadata hash to allow the proc to check if it even has the key. | if value.arity == 2 | ||
# This is necessary for the implicit :if exclusion filter: | # Pass the metadata hash to allow the proc to check if it even has the key. | ||
# { } # => run the example | # This is necessary for the implicit :if exclusion filter: | ||
# { :if => nil } # => exclude the example | # { } # => run the example | ||
# The value of metadata[:if] is the same in these two cases but | # { :if => nil } # => exclude the example | ||
# they need to be treated differently. | # The value of metadata[:if] is the same in these two cases but | ||
value.call(metadata[key], metadata) rescue false | # they need to be treated differently. | ||
value.call(metadata[key], metadata) rescue false | |||
else | |||
value.call(metadata[key]) rescue false | |||
end | |||
else | else | ||
value.call(metadata[key]) rescue false | metadata[key].to_s == value.to_s | ||
end | end | ||
when String | |||
metadata[key].to_s == value | |||
This comment has been minimized.
Sorry, something went wrong.
AlexKVal
Contributor
|
|||
when Enumerable | |||
key == :line_numbers ? within_examples_lines?(value, metadata) : metadata[key] == value | |||
else | |||
metadata[key].to_s == value.to_s | |||
end | end | ||
end | end | ||
|
|
||
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 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 | |||
|
|||
protected | protected | ||
|
|
||
def configure_for_example(description, user_metadata) | def configure_for_example(description, user_metadata) | ||
|
@@ -223,24 +232,14 @@ def ensure_valid_keys(user_metadata) | ||
end | end | ||
end | end | ||
|
|
||
def relevant_line_numbers(meta) | def example_group_declaration_line(locations) | ||
[meta[:line_number]] + (meta[:example_group] ? relevant_line_numbers(meta[:example_group]) : []) | locations[File.expand_path(self[:example_group][:file_path])] if self[:example_group] | ||
end | |||
|
|||
def within_examples_lines?(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 | end | ||
|
|
||
def example_group_line_number(locations, metadata) | # TODO - make this a method on metadata - the problem is | ||
# An ExampleGroup always got one line number | # metadata[:example_group] is not always a kind of GroupMetadataHash. | ||
This comment has been minimized.
Sorry, something went wrong.
AlexKVal
Contributor
|
|||
locations[File.expand_path( metadata[:example_group][:file_path] )] if metadata[:example_group] | def relevant_line_numbers(metadata=self) | ||
end | [metadata[:line_number]] + (metadata[:example_group] ? relevant_line_numbers(metadata[:example_group]) : []) | ||
|
|||
def filter_for_locations?(locations, metadata) | |||
# it ignores location filters for other files | |||
line_number = example_group_line_number(locations, metadata) | |||
line_number ? within_examples_lines?(line_number, metadata) : true | |||
end | end | ||
|
|
||
end | end | ||
|
2 comments
on commit 742a658
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I've learned much from this refactoring. It's all very new for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
location_filter_applies? and line_number_filter_applies? aren't they private ? (or at least with a @Private tag)
I was wanted to do like this, but was afraid of a nested case. But in the end the method looks more clean. IMHO.