lib/cucumber_analytics/feature.rb
module CucumberAnalytics
# A class modeling a Cucumber Feature.
class Feature < FeatureElement
include Taggable
include Containing
# The Background object contained by the Feature
attr_accessor :background
# The TestElement objects contained by the Feature
attr_accessor :tests
# Creates a new Feature object and, if *source* is provided, populates the
# object.
def initialize(source = nil)
parsed_feature = process_source(source)
super(parsed_feature)
@tags = []
@tag_elements = []
@tests = []
build_feature(parsed_feature) if parsed_feature
end
# Returns true if the feature contains a background, false otherwise.
def has_background?
!@background.nil?
end
# Returns the scenarios contained in the feature.
def scenarios
@tests.select { |test| test.is_a? Scenario }
end
# Returns the outlines contained in the feature.
def outlines
@tests.select { |test| test.is_a? Outline }
end
# Returns the number of scenarios contained in the feature.
def scenario_count
scenarios.count
end
# Returns the number of outlines contained in the feature.
def outline_count
outlines.count
end
# Returns the number of tests contained in the feature.
def test_count
@tests.count
end
# Returns the number of test cases contained in the feature.
def test_case_count
scenario_count + outlines.reduce(0) { |outline_sum, outline|
outline_sum += outline.examples.reduce(0) { |example_sum, example|
example_sum += example.rows.count
}
}
end
# Returns the immediate child elements of the feature (i.e. its Background,
# Scenario, and Outline objects.
def contains
@background ? [@background] + @tests : @tests
end
# Returns gherkin representation of the feature.
def to_s
text = ''
text << tag_output_string + "\n" unless tags.empty?
text << "Feature:#{name_output_string}"
text << "\n" + description_output_string unless description_text.empty?
text << "\n\n" + background_output_string if background
text << "\n\n" + tests_output_string unless tests.empty?
text
end
private
def process_source(source)
case
when source.is_a?(String)
parse_feature(source)
else
source
end
end
def parse_feature(source_text)
parsed_file = Parsing::parse_text(source_text)
parsed_file.first
end
def build_feature(parsed_feature)
populate_element_tags(parsed_feature)
populate_feature_elements(parsed_feature)
end
def populate_feature_elements(parsed_feature)
elements = parsed_feature['elements']
if elements
elements.each do |element|
case element['keyword']
when 'Scenario'
@tests << build_child_element(Scenario, element)
when 'Scenario Outline'
@tests << build_child_element(Outline, element)
when 'Background'
@background = build_child_element(Background, element)
else
raise(ArgumentError, "Unknown keyword: #{element['keyword']}")
end
end
end
end
def background_output_string
test_element_output_string(background)
end
def tests_output_string
tests.collect { |test| test_element_output_string(test) }.join("\n\n")
end
def test_element_output_string(test_element)
test_element.to_s.split("\n").collect { |line| line.empty? ? '' : " #{line}" }.join("\n")
end
end
end