1 # Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are met:
5 # 1. Redistributions of source code must retain the above copyright notice,
6 # this list of conditions and the following disclaimer.
7 # 2. Redistributions in binary form must reproduce the above copyright notice,
8 # this list of conditions and the following disclaimer in the documentation
9 # and/or other materials provided with the distribution.
11 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
12 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
15 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
16 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
17 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
19 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
20 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 # POSSIBILITY OF SUCH DAMAGE.
23 require File.expand_path('../spec_helper', File.dirname(__FILE__))
25 describe Walrat::ParsletRepetition do
26 it 'raises if "parseable" argument is nil' do
28 Walrat::ParsletRepetition.new nil, 0
29 end.to raise_error(ArgumentError, /nil parseable/)
32 it 'raises if "min" argument is nil' do
34 Walrat::ParsletRepetition.new 'foo'.to_parseable, nil
35 end.to raise_error(ArgumentError, /nil min/)
38 it 'raises if passed nil string for parsing' do
40 Walrat::ParsletRepetition.new('foo'.to_parseable, 0).parse nil
41 end.to raise_error(ArgumentError, /nil string/)
44 it 'should be able to match "zero or more" times (like "*" in regular expressions)' do
45 parslet = Walrat::ParsletRepetition.new 'foo'.to_parseable, 0
48 end.to throw_symbol(:ZeroWidthParseSuccess) # zero times
49 parslet.parse('foo').should == 'foo' # one time
50 parslet.parse('foofoo').should == ['foo', 'foo'] # two times
51 parslet.parse('foofoofoobar').should == ['foo', 'foo', 'foo'] # three times
54 it 'should be able to match "zero or one" times (like "?" in regular expressions)' do
55 parslet = Walrat::ParsletRepetition.new 'foo'.to_parseable, 0, 1
58 end.to throw_symbol(:ZeroWidthParseSuccess) # zero times
59 parslet.parse('foo').should == 'foo' # one time
60 parslet.parse('foofoo').should == 'foo' # stop at one time
63 it 'should be able to match "one or more" times (like "+" in regular expressions)' do
64 parslet = Walrat::ParsletRepetition.new 'foo'.to_parseable, 1
67 end.to raise_error(Walrat::ParseError) # zero times (error)
68 parslet.parse('foo').should == 'foo' # one time
69 parslet.parse('foofoo').should == ['foo', 'foo'] # two times
70 parslet.parse('foofoofoobar').should == ['foo', 'foo', 'foo'] # three times
73 it 'should be able to match "between X and Y" times (like {X, Y} in regular expressions)' do
74 parslet = Walrat::ParsletRepetition.new 'foo'.to_parseable, 2, 3
77 end.to raise_error(Walrat::ParseError) # zero times (error)
80 end.to raise_error(Walrat::ParseError) # one time (error)
81 parslet.parse('foofoo').should == ['foo', 'foo'] # two times
82 parslet.parse('foofoofoo').should == ['foo', 'foo', 'foo'] # three times
83 parslet.parse('foofoofoofoo').should == ['foo', 'foo', 'foo'] # stop at three times
86 it 'matches should be greedy' do
87 # here the ParsletRepetition should consume all the "foos", leaving nothing
88 # for the final parslet
89 parslet = Walrat::ParsletRepetition.new('foo'.to_parseable, 1) & 'foo'
91 parslet.parse 'foofoofoofoo'
92 end.to raise_error(Walrat::ParseError)
95 it 'should be able to compare for equality' do
96 Walrat::ParsletRepetition.new('foo'.to_parseable, 1).
97 should eql(Walrat::ParsletRepetition.new('foo'.to_parseable, 1))
98 Walrat::ParsletRepetition.new('foo'.to_parseable, 1).
99 should_not eql(Walrat::ParsletRepetition.new('bar'.to_parseable, 1))
100 Walrat::ParsletRepetition.new('foo'.to_parseable, 1).
101 should_not eql(Walrat::ParsletRepetition.new('foo'.to_parseable, 2))