]> git.wincent.com - walrat.git/blob - spec/walrat/parslet_repetition_spec.rb
Initial import (extraction from Walrus repo, commit 0c9d44c)
[walrat.git] / spec / walrat / parslet_repetition_spec.rb
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:
4 #
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.
10 #
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.
22
23 require File.expand_path('../spec_helper', File.dirname(__FILE__))
24
25 describe Walrat::ParsletRepetition do
26   it 'raises if "parseable" argument is nil' do
27     expect do
28       Walrat::ParsletRepetition.new nil, 0
29     end.to raise_error(ArgumentError, /nil parseable/)
30   end
31
32   it 'raises if "min" argument is nil' do
33     expect do
34       Walrat::ParsletRepetition.new 'foo'.to_parseable, nil
35     end.to raise_error(ArgumentError, /nil min/)
36   end
37
38   it 'raises if passed nil string for parsing' do
39     expect do
40       Walrat::ParsletRepetition.new('foo'.to_parseable, 0).parse nil
41     end.to raise_error(ArgumentError, /nil string/)
42   end
43
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
46     expect do
47       parslet.parse 'bar'
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
52   end
53
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
56     expect do
57       parslet.parse 'bar'
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
61   end
62
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
65     expect do
66       parslet.parse 'bar'
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
71   end
72
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
75     expect do
76       parslet.parse 'bar'
77     end.to raise_error(Walrat::ParseError)                        # zero times (error)
78     expect do
79       parslet.parse 'foo'
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
84   end
85
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'
90     expect do
91       parslet.parse 'foofoofoofoo'
92     end.to raise_error(Walrat::ParseError)
93   end
94
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))
102   end
103 end