Class: Shallot

Inherits:
Object
  • Object
show all
Defined in:
lib/shallot.rb

Overview

shallot exposes only one class; Shallot. A Shallot instance encompasses the state of the parsing operation, which can be advanced by feeding it lines of gherkin. That sounded weird. The Shallot class also exposes methods to wrap the instance, allowing you to quickly serve parsed feature files.

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeShallot

Creates a fresh Shallot instance.



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/shallot.rb', line 44

def initialize
  @state = :opening
  @file_tags = []
  @scenario_tags = []
  @qqq = nil
  @scenario = nil
  @line = 0

  @background = []
  @scenarios = []
  @feature = nil
end

Instance Attribute Details

#backgroundObject (readonly)

A list of strings; the lines comprising the Background steps.



61
62
63
# File 'lib/shallot.rb', line 61

def background
  @background
end

#featureObject (readonly)

The name of the feature, as specified on the “Feature:” line.



58
59
60
# File 'lib/shallot.rb', line 58

def feature
  @feature
end

#scenariosObject (readonly)

A list of hashes for each Scenario or Scenario Outline; the hash contains:

  • :name: the name as given on the “Scenario:” or “Scenario Outline:” line

  • :outline: true if this is a Scenario Outline, false if Scenario

  • :tags: the list of tags for this scenario (sans “@”), including feature-wide tags

  • :contents: the list of steps (one string per line), including all whitespace, tables, etc.



70
71
72
# File 'lib/shallot.rb', line 70

def scenarios
  @scenarios
end

Class Method Details

.parse(file) ⇒ Object

Parses file in its entirety (by creating a new Shallot instance), and returns a hash with :feature, :background and :scenarios keys as for the Shallot instance object. file only needs to implement each_line. If an error occurs, Shallot::Error will be thrown.



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/shallot.rb', line 31

def self.parse file
  parser = new
  file.each_line {|line| parser.parse line}
  parser.eof!

  {
    feature:    parser.feature,
    background: parser.background,
    scenarios:  parser.scenarios,
  }
end

Instance Method Details

#eof!Object

Signals to the parser that the end of the file has been reached. This may throw Shallot::Error if EOF wasn’t expected in its current state.

Raises:



101
102
103
104
105
# File 'lib/shallot.rb', line 101

def eof!
  method = :"eof_#@state"
  raise Error, "no eof handler for #@state" unless respond_to? method
  send method
end

#parse(line) ⇒ Object

Parses the next line, line. Parse or internal errors may cause Shallot::Error to be thrown.

Raises:



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/shallot.rb', line 74

def parse line
  # Check some conditions that should be (more or less) invariant across
  # a feature file.
  @line += 1
  
  if @qqq.nil? and %w{''' """}.include? line.strip
    # Start triple-quote.
    @qqq = line.strip

  elsif @qqq == line.strip
    # End triple-quote.
    @qqq = nil

  elsif @qqq.nil? and [nil, ?#].include? line.strip[0]
    # Blank or comment; outside triple-quote.  Process as an empty line.
    line = '' unless [:background, :scenario].include? @state
  end

  # Use state.
  
  method = :"parse_#@state"
  raise Error, "no parser for #@state" unless respond_to? method
  send method, line
end