class RainforestCli::TestParser::Parser

Constants

CSV_FIELDS
TEST_DATA_FIELDS

Attributes

errors[R]
steps[R]
text[R]

Public Class Methods

new(file_name) click to toggle source
# File lib/rainforest_cli/test_parser.rb, line 20
def initialize(file_name)
  @text = File.read(file_name).to_s

  @test = Test.new
  @test.file_name = File.expand_path(file_name)
  @test.start_uri = '/'
  @test.description = ''
  @test.steps = []
  @test.errors = {}
  @test.tags = []
  @test.browsers = []
end

Public Instance Methods

process() click to toggle source
# File lib/rainforest_cli/test_parser.rb, line 36
def process
  step_scratch = []
  step_settings_scratch = {}

  text.lines.each_with_index do |line, line_no|
    line = line.chomp
    if line[0..1] == '#!'
      @test.rfml_id = line[2..-1].strip.split(' ')[0]

    elsif line[0] == '#'
      comment = line[1..-1].strip

      if comment.start_with?('redirect:')
        value = comment.split(' ')[1..-1].join(' ').strip
        if %(true false).include?(value)
          step_settings_scratch[:redirect] = value
        else
          @test.errors[line_no] = Error.new(line_no, 'Redirection value must be true or false')
        end
      else
        matched_field = TEST_DATA_FIELDS.find { |f| comment.start_with?("#{f}:") }
        if matched_field.nil?
          # comment, store in description
          @test.description += comment + "\n"
        else
          # extract just the text of the field
          @test[matched_field] = comment.split(' ')[1..-1].join(' ').strip

          # if it's supposed to be a CSV field, split and trim it
          if CSV_FIELDS.include?(matched_field)
            @test[matched_field] = @test[matched_field].split(',').map(&:strip).map(&:downcase)
          end
        end
      end

    elsif step_scratch.count == 0 && line.strip != ''
      if line[0] == '-'
        @test.steps << EmbeddedTest.new(line[1..-1].strip, step_settings_scratch[:redirect])
        step_settings_scratch = {}
      else
        step_scratch << line.strip
      end

    elsif step_scratch.count == 1
      if line.strip == ''
        @test.errors[line_no] = Error.new(line_no, 'Missing question')
      elsif !line.include?('?')
        @test.errors[line_no] = Error.new(line_no, 'Missing ?')
      else
        step_scratch << line.strip
      end

    elsif line.strip.empty? && step_settings_scratch.any?
      @test.errors[line_no] = Error.new(line_no, 'Extra space between step attributes and step content.')
    end

    if @test.errors.has_key?(line_no)
      step_scratch = []
    end

    if step_scratch.count == 2
      @test.steps << Step.new(step_scratch[0], step_scratch[1], step_settings_scratch[:redirect])
      step_scratch = []
      step_settings_scratch = {}
    end
  end

  if @test.rfml_id == nil
    @test.errors[:rfml_id] = Error.new(:rfml_id, 'Missing RFML ID. Please start a line #! followed by a unique id.')
  end

  if @test.title.nil? || @test.title.empty?
    @test.errors[:title] = Error.new(
      :title,
      'Missing Title for test. Please start a line with "# title: " and specify your test title.',
    )
  end

  return @test
end