]> git.wincent.com - walrat.git/blob - spec/walrat/string_parslet_spec.rb
Initial import (extraction from Walrus repo, commit 0c9d44c)
[walrat.git] / spec / walrat / string_parslet_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::StringParslet do
26   before do
27     @parslet = Walrat::StringParslet.new('HELLO')
28   end
29
30   it 'should raise an ArgumentError if initialized with nil' do
31     lambda { Walrat::StringParslet.new(nil) }.should raise_error(ArgumentError)
32   end
33
34   it 'parse should succeed if the input string matches' do
35     lambda { @parslet.parse('HELLO') }.should_not raise_error
36   end
37
38   it 'parse should succeed if the input string matches, even if it continues after the match' do
39     lambda { @parslet.parse('HELLO...') }.should_not raise_error
40   end
41
42   it 'parse should return parsed string' do
43     @parslet.parse('HELLO').should == 'HELLO'
44     @parslet.parse('HELLO...').should == 'HELLO'
45   end
46
47   it 'parse should raise an ArgumentError if passed nil' do
48     lambda { @parslet.parse(nil) }.should raise_error(ArgumentError)
49   end
50
51   it 'parse should raise a ParseError if the input string does not match' do
52     lambda { @parslet.parse('GOODBYE') }.should raise_error(Walrat::ParseError)        # total mismatch
53     lambda { @parslet.parse('GOODBYE, HELLO') }.should raise_error(Walrat::ParseError) # eventually would match, but too late
54     lambda { @parslet.parse('HELL...') }.should raise_error(Walrat::ParseError)        # starts well, but fails
55     lambda { @parslet.parse(' HELLO') }.should raise_error(Walrat::ParseError)         # note the leading whitespace
56     lambda { @parslet.parse('') }.should raise_error(Walrat::ParseError)               # empty strings can't match
57   end
58
59   it 'parse exceptions should include a detailed error message' do
60     # TODO: catch the raised exception and compare the message
61     lambda { @parslet.parse('HELL...') }.should raise_error(Walrat::ParseError)
62     lambda { @parslet.parse('HELL') }.should raise_error(Walrat::ParseError)
63   end
64
65   it 'should be able to compare string parslets for equality' do
66     'foo'.to_parseable.should eql('foo'.to_parseable)           # equal
67     'foo'.to_parseable.should_not eql('bar'.to_parseable)       # different
68     'foo'.to_parseable.should_not eql('Foo'.to_parseable)       # differing only in case
69     'foo'.to_parseable.should_not eql(/foo/)                    # totally different classes
70   end
71
72   it 'should accurately pack line and column ends into whatever is returned by "parse"' do
73     # single word
74     parslet = 'hello'.to_parseable
75     result = parslet.parse('hello')
76     result.line_end.should == 0
77     result.column_end.should == 5
78
79     # single word with newline at end (UNIX style)
80     parslet = "hello\n".to_parseable
81     result = parslet.parse("hello\n")
82     result.line_end.should == 1
83     result.column_end.should == 0
84
85     # single word with newline at end (Classic Mac style)
86     parslet = "hello\r".to_parseable
87     result = parslet.parse("hello\r")
88     result.line_end.should == 1
89     result.column_end.should == 0
90
91     # single word with newline at end (Windows style)
92     parslet = "hello\r\n".to_parseable
93     result = parslet.parse("hello\r\n")
94     result.line_end.should == 1
95     result.column_end.should == 0
96
97     # two lines (UNIX style)
98     parslet = "hello\nworld".to_parseable
99     result = parslet.parse("hello\nworld")
100     result.line_end.should == 1
101     result.column_end.should == 5
102
103     # two lines (Classic Mac style)
104     parslet = "hello\rworld".to_parseable
105     result = parslet.parse("hello\rworld")
106     result.line_end.should == 1
107     result.column_end.should == 5
108
109     # two lines (Windows style)
110     parslet = "hello\r\nworld".to_parseable
111     result = parslet.parse("hello\r\nworld")
112     result.line_end.should == 1
113     result.column_end.should == 5
114   end
115
116   it 'line and column end should reflect last succesfully scanned position prior to failure' do
117     # fail right at start
118     parslet = "hello\r\nworld".to_parseable
119     begin
120       parslet.parse('foobar')
121     rescue Walrat::ParseError => e
122       exception = e
123     end
124     exception.line_end.should == 0
125     exception.column_end.should == 0
126
127     # fail after 1 character
128     begin
129       parslet.parse('hfoobar')
130     rescue Walrat::ParseError => e
131       exception = e
132     end
133     exception.line_end.should == 0
134     exception.column_end.should == 1
135
136     # fail after end-of-line
137     begin
138       parslet.parse("hello\r\nfoobar")
139     rescue Walrat::ParseError => e
140       exception = e
141     end
142     exception.line_end.should == 1
143     exception.column_end.should == 0
144   end
145 end