module CucumberAnalytics # A class modeling a Cucumber Examples table. class Example < FeatureElement include Taggable # The argument rows in the example table attr_accessor :rows # The parameters for the example table attr_accessor :parameters # Creates a new Example object and, if *source* is provided, # populates the object. def initialize(source = nil) parsed_example = process_source(source) super(parsed_example) @tags = [] @rows = [] @parameters = [] build_example(parsed_example) if parsed_example end # Adds a row to the example table. The row can be given as a Hash of # parameters and their corresponding values or as an Array of values which # will be assigned in order. def add_row(row) case when row.is_a?(Array) @rows << Hash[@parameters.zip(row.collect { |value| value.strip })] when row.is_a?(Hash) @rows << row.each_value { |value| value.strip! } else raise(ArgumentError, "Can only add row from a Hash or an Array but received #{row.class}") end end # Removes a row from the example table. The row can be given as a Hash of # parameters and their corresponding values or as an Array of values # which will be assigned in order. def remove_row(row) case when row.is_a?(Array) location = @rows.index { |row_hash| row_hash.values_at(*@parameters) == row.collect { |value| value.strip } } when row.is_a?(Hash) location = @rows.index { |row_hash| row_hash == row.each_value { |value| value.strip! } } else raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row.class}") end @rows.delete_at(location) if location end private def process_source(source) case when source.is_a?(String) parse_example(source) else source end end def parse_example(source_text) base_file_string = "Feature: Fake feature to parse\nScenario Outline:\n* fake step\n" source_text = base_file_string + source_text parsed_file = Parsing::parse_text(source_text) parsed_file.first['elements'].first['examples'].first end def build_example(parsed_example) populate_element_tags(parsed_example) populate_example_parameters(parsed_example) populate_example_rows(parsed_example) end def populate_example_parameters(parsed_example) @parameters = parsed_example['rows'].first['cells'] end def populate_example_rows(parsed_example) parsed_example['rows'].shift parsed_example['rows'].each do |row| @rows << Hash[@parameters.zip(row['cells'])] end end end end