class Spectro::Spec::Parser

Parser to get Spectro::Spec instances from the metadata on the program's files

Attributes

file_path[RW]

Public Class Methods

new(file_path) click to toggle source

@param [String] file_path the path of the file to parse

# File lib/spectro/spec/parser.rb, line 13
def initialize file_path
  self.file_path = file_path
end
parse(file_path) click to toggle source

Create an instance of Spectro::Spec::Parser for the given file path and returns the parse response (the collection of Spectro::Spec instances for the given file)

@param [String] file_path the path of the file to parse @return [<Spectro::Spec>] collection of specs found in the given file path

# File lib/spectro/spec/parser.rb, line 23
def self.parse(file_path)
  Spectro::Spec::Parser.new(file_path).parse
end

Public Instance Methods

parse() click to toggle source

Looks for specs on the given file and parses them as Spectro::Specs

@return [<Spectro::Spec>] collection of specs found in the given file path

# File lib/spectro/spec/parser.rb, line 30
def parse
  /.*^__END__$(?<raw_specs>.*)\Z/m =~ File.read(self.file_path)
  return raw_specs.split('spec_for')[1..-1].map do |raw_spec|
    self.parse_spec raw_spec
  end
end
parse_spec(raw_spec) click to toggle source

Parses a raw spec and returns an Spectro::Spec instance

@param [String] raw_spec raw spec @return [Spectro::Spec] the Spectro::Spec instance

# File lib/spectro/spec/parser.rb, line 41
def parse_spec raw_spec
  spec_raw_signature, *spec_raw_desc_and_rules  = raw_spec.split("\n").reject(&:empty?)

  spec_signature = self.parse_spec_signature(spec_raw_signature)

  spec_raw_description = spec_raw_desc_and_rules.take_while do |desc_or_rule|
    desc_or_rule.match(/^`/)
  end

  spec_description = self.parse_spec_description(spec_raw_description)

  spec_raw_rules = spec_raw_desc_and_rules - spec_raw_description

  spec_rules = spec_raw_rules.map do |spec_raw_rule|
    self.parse_spec_rule(spec_raw_rule)
  end

  spec_md5 = Digest::MD5.hexdigest(raw_spec)

  return Spectro::Spec.new(spec_md5, spec_signature, spec_description, spec_rules)
end
parse_spec_description(spec_raw_description) click to toggle source

Returns the spec description from the raw spec description

@param [String] spec_raw_description spec's raw description @return [String] spec description

# File lib/spectro/spec/parser.rb, line 67
def parse_spec_description(spec_raw_description)
  return spec_raw_description.collect do |raw_description|
    if raw_description[1..-1].empty?
      next "\n"
    end

    next raw_description[1..-1].strip
  end.join(' ').strip.gsub("\n ", "\n")
end
parse_spec_rule(spec_raw_rule) click to toggle source

Returns an Spectro::Spec::Rule instance from the raw spec rule

@param [String] spec_raw_rule raw rule of the spec @return [Spectro::Spec::Rule] spec rule instance

# File lib/spectro/spec/parser.rb, line 81
def parse_spec_rule spec_raw_rule
  # REGEX HERE PLEASE, F%#&!@* EASY
  raw_params, raw_output = spec_raw_rule.split('->').map(&:strip)
  output = eval(raw_output)
  params = raw_params.split(/,\s+/).map do |raw_param|
    eval(raw_param)
  end

  return Spectro::Spec::Rule.new(params, output)
end
parse_spec_signature(spec_raw_signature) click to toggle source

Returns a Spectro::Spec::Signature from the raw spec signature

@param [String] spec_raw_signature raw signature of the spec @param [<Spectro::Spec::Signature] spec signature instance

# File lib/spectro/spec/parser.rb, line 96
def parse_spec_signature spec_raw_signature
  # REGEX HERE PLEASE, F%#&!@* EASY
  raw_name_and_params_types, output_type = spec_raw_signature.split('->').map(&:strip)
  name, *params_types = raw_name_and_params_types.split(/,?\s+/).map(&:strip)

  return Spectro::Spec::Signature.new(name, params_types, output_type)
end