Module: Rattler::Util::ParserSpecHelper

Defined in:
lib/rattler/util/parser_spec_helper.rb

Overview

ParserSpecHelper defines a fluent interface for writing RSpec examples for parsers.

Examples:


require 'rattler/grammar/grammar_parser'
require 'rattler/util/parser_spec_helper'

describe Rattler::Grammar::GrammarParser do
  include Rattler::Util::ParserSpecHelper

  describe '#match(:var_name)' do
    it 'recognizes variable names' do
      matching(' fooBar ').as(:var_name).should result_in('fooBar').at(7)
      matching(' FooBar ').as(:var_name).should fail.with_message('variable name expected')
    end
  end
end

Author:

  • Jason Arhart

Defined Under Namespace

Classes: Matching, Parsing

Instance Method Summary collapse

Instance Method Details

#failMatcher

Expect parse to fail.

parsing(source).as(rule_name).should fail

Passes if parsing source with parser_class fails.

parsing(source).as(rule_name).should fail.at(pos)

Passes if parsing source with parser_class fails with the parse position at pos

Returns:

  • (Matcher)


114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/rattler/util/parser_spec_helper.rb', line 114

RSpec::Matchers.define :fail do
  match do |target|
    !target.result &&
    (!@expected_message || (target.failure.message == @expected_message)) &&
    (!@expected_pos || (target.failure.pos == @expected_pos))
  end

  chain :with_message do |message|
    @expected_message = message
  end

  chain :at do |pos|
    @expected_pos = pos
  end

  failure_message_for_should do |target|
    if target.result
      "expected parse to fail but got #{target.result.inspect}"
    elsif @expected_message && (target.failure.message != @expected_message)
      <<-MESSAGE
incorrect failure message
expected #{@expected_message.inspect}
 got #{target.failure.message.inspect}
MESSAGE
    else
      <<-MESSAGE
incorrect failure position
expected #{@expected_pos.inspect}
 got #{target.failure.pos.inspect}
MESSAGE
    end
  end
end

#matching(source) ⇒ Object

Return a match result to be matched using #result_in or #fail

matching(source).as(rule_name)
matching(source).as(rule_name).from(pos)


48
49
50
# File 'lib/rattler/util/parser_spec_helper.rb', line 48

def matching(source)
  Matching.new(parser(source))
end

#parser(source) ⇒ Object



52
53
54
# File 'lib/rattler/util/parser_spec_helper.rb', line 52

def parser(source)
  (self.respond_to?(:parser_class) ? parser_class : described_class).new(source)
end

#parsing(source) ⇒ Object

Return a parse result to be matched using #result_in or #fail

parsing(source)
parsing(source).from(pos)


39
40
41
# File 'lib/rattler/util/parser_spec_helper.rb', line 39

def parsing(source)
  Parsing.new(parser(source))
end

#result_inMatcher

Expect parse to succeed.

parsing(source).should result_in(result)

Passes if parsing source succeeds returning result.

parsing(source).should result_in(result).at(pos)

Passes if parsing source succeeds returning result with the parse position at pos.

Returns:

  • (Matcher)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rattler/util/parser_spec_helper.rb', line 68

RSpec::Matchers.define :result_in do |expected|
  match do |target|
    (target.result == expected) and
    (not @expected_pos or
      target.pos == @expected_pos) and
    (not @expected_bindings or
      @expected_bindings.all?{|k, v| target.scope[k] == v })
  end

  chain :at do |pos|
    @expected_pos = pos
  end

  chain :with_scope do |bindings|
    @expected_bindings = bindings
  end

  failure_message_for_should do |target|
    if target.result != expected
      <<-MESSAGE
incorrect parse result
expected #{expected.inspect}
 got #{target.result.inspect}
MESSAGE
    else
      <<-MESSAGE
incorrect parse position
expected #{@expected_pos.inspect}
 got #{target.pos.inspect}
MESSAGE
    end
  end
end