Skip to content

Commit

Permalink
+ Improve RSpec matcher.
Browse files Browse the repository at this point in the history
RSpec matcher :as chain now accepts a block. This allows for partial
assertions on the output, rather than just equality.

Also: try :trace => true in parse for error traces output.
  • Loading branch information
Josep M. Bach authored and kschiess committed Feb 21, 2011
1 parent c48baaf commit 99c3528
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
40 changes: 27 additions & 13 deletions lib/parslet/rig/rspec.rb
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
RSpec::Matchers.define(:parse) do |input, opts|
chain(:as) { |as| @as = as }

match do |parser|
begin
@result = parser.parse(input)
@as == @result or @as.nil?
@block ? @block.call(@result)
: (@as == @result || @as.nil?)
rescue Parslet::ParseFailed
@trace = parser.error_tree.ascii_tree if opts && opts[:trace]
false
end
end

failure_message_for_should do |is|
"expected " <<
(@as ?
"output of parsing #{input.inspect} with #{is.inspect} to equal #{@as.inspect}, but was #{@result.inspect}" :
"#{is.inspect} to be able to parse #{input.inspect}") <<
(@trace ?
"\n"+@trace : '')
if @block
"expected output of parsing #{input.inspect}" <<
" with #{is.inspect} to meet block conditions, but it didn't"
else
"expected " <<
(@as ? "output of parsing #{input.inspect}"<<
" with #{is.inspect} to equal #{@as.inspect}, but was #{@result.inspect}"
: "#{is.inspect} to be able to parse #{input.inspect}") <<
(@trace ? "\n"+@trace
: '')
end
end

failure_message_for_should_not do |is|
"expected " <<
(@as ?
"output of parsing #{input.inspect} with #{is.inspect} not to equal #{@as.inspect}" :
"#{is.inspect} to not parse #{input.inspect}, but it did")
if @block
"expected output of parsing #{input.inspect} with #{is.inspect} not to meet block conditions, but it did"
else
"expected " <<
(@as ? "output of parsing #{input.inspect}"<<
" with #{is.inspect} not to equal #{@as.inspect}"
: "#{is.inspect} to not parse #{input.inspect}, but it did")
end
end

def as(expected_output = nil, &block)
@as = expected_output
@block = block
self
end
end
17 changes: 13 additions & 4 deletions spec/parslet/rig/rspec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@
it { str('foo').as(:bar).should parse('foo').as({:bar => 'foo'}) }
it { str('foo').as(:bar).should_not parse('foo').as({:b => 'f'}) }

it 'accepts a block to assert more specific details about the parsing output' do
str('foo').as(:bar).should(parse('foo').as { |output|
output.should have_key(:bar)
output.values.first.should == 'foo'
})
end

# Uncomment to test error messages manually:
# it { str('foo').should parse('foo', :trace => true).as('bar') }
# it { str('foo').should parse('food', :trace => true) }
# it { str('foo').should_not parse('foo', :trace => true).as('foo') }
# it { str('foo').should_not parse('foo', :trace => true) }
# it { str('foo').should parse('foo').as('bar') }
# it { str('foo').should parse('food') }
# it { str('foo').should_not parse('foo').as('foo') }
# it { str('foo').should_not parse('foo') }
# it 'accepts a block to assert more specific details about the parsing output' do
# str('foo').as(:bar).should(parse('foo', :trace => true).as { |output|
# output.should_not have_key(:bar)
# })
# end

end

0 comments on commit 99c3528

Please sign in to comment.