walrus 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/walrus +44 -0
- data/ext/jindex/extconf.rb +11 -0
- data/ext/jindex/jindex.c +79 -0
- data/ext/mkdtemp/extconf.rb +11 -0
- data/ext/mkdtemp/mkdtemp.c +41 -0
- data/lib/walrus/additions/module.rb +36 -0
- data/lib/walrus/additions/string.rb +37 -0
- data/lib/walrus/additions/test/unit/error_collector.rb +62 -0
- data/lib/walrus/compile_error.rb +28 -0
- data/lib/walrus/compiler.rb +124 -0
- data/lib/walrus/contrib/spec/walruscloth_spec.rb +32 -0
- data/lib/walrus/contrib/walruscloth.rb +82 -0
- data/lib/walrus/diff.rb +89 -0
- data/lib/walrus/document.rb +98 -0
- data/lib/walrus/grammar/additions/proc.rb +20 -0
- data/lib/walrus/grammar/additions/regexp.rb +21 -0
- data/lib/walrus/grammar/additions/string.rb +52 -0
- data/lib/walrus/grammar/additions/symbol.rb +42 -0
- data/lib/walrus/grammar/and_predicate.rb +40 -0
- data/lib/walrus/grammar/array_result.rb +19 -0
- data/lib/walrus/grammar/continuation_wrapper_exception.rb +28 -0
- data/lib/walrus/grammar/left_recursion_exception.rb +27 -0
- data/lib/walrus/grammar/location_tracking.rb +105 -0
- data/lib/walrus/grammar/match_data_wrapper.rb +65 -0
- data/lib/walrus/grammar/memoizing.rb +41 -0
- data/lib/walrus/grammar/memoizing_cache.rb +94 -0
- data/lib/walrus/grammar/node.rb +60 -0
- data/lib/walrus/grammar/not_predicate.rb +40 -0
- data/lib/walrus/grammar/parse_error.rb +39 -0
- data/lib/walrus/grammar/parser_state.rb +181 -0
- data/lib/walrus/grammar/parslet.rb +28 -0
- data/lib/walrus/grammar/parslet_choice.rb +120 -0
- data/lib/walrus/grammar/parslet_combination.rb +26 -0
- data/lib/walrus/grammar/parslet_combining.rb +154 -0
- data/lib/walrus/grammar/parslet_merge.rb +88 -0
- data/lib/walrus/grammar/parslet_omission.rb +57 -0
- data/lib/walrus/grammar/parslet_repetition.rb +97 -0
- data/lib/walrus/grammar/parslet_repetition_default.rb +58 -0
- data/lib/walrus/grammar/parslet_sequence.rb +202 -0
- data/lib/walrus/grammar/predicate.rb +57 -0
- data/lib/walrus/grammar/proc_parslet.rb +52 -0
- data/lib/walrus/grammar/regexp_parslet.rb +73 -0
- data/lib/walrus/grammar/skipped_substring_exception.rb +36 -0
- data/lib/walrus/grammar/string_enumerator.rb +45 -0
- data/lib/walrus/grammar/string_parslet.rb +75 -0
- data/lib/walrus/grammar/string_result.rb +24 -0
- data/lib/walrus/grammar/symbol_parslet.rb +63 -0
- data/lib/walrus/grammar.rb +170 -0
- data/lib/walrus/no_parameter_marker.rb +19 -0
- data/lib/walrus/parser.rb +420 -0
- data/lib/walrus/runner.rb +356 -0
- data/lib/walrus/template.rb +75 -0
- data/lib/walrus/walrus_grammar/assignment_expression.rb +24 -0
- data/lib/walrus/walrus_grammar/block_directive.rb +28 -0
- data/lib/walrus/walrus_grammar/comment.rb +24 -0
- data/lib/walrus/walrus_grammar/def_directive.rb +64 -0
- data/lib/walrus/walrus_grammar/echo_directive.rb +44 -0
- data/lib/walrus/walrus_grammar/escape_sequence.rb +24 -0
- data/lib/walrus/walrus_grammar/import_directive.rb +44 -0
- data/lib/walrus/walrus_grammar/include_directive.rb +27 -0
- data/lib/walrus/walrus_grammar/instance_variable.rb +24 -0
- data/lib/walrus/walrus_grammar/literal.rb +24 -0
- data/lib/walrus/walrus_grammar/message_expression.rb +25 -0
- data/lib/walrus/walrus_grammar/multiline_comment.rb +54 -0
- data/lib/walrus/walrus_grammar/placeholder.rb +40 -0
- data/lib/walrus/walrus_grammar/raw_directive.rb +42 -0
- data/lib/walrus/walrus_grammar/raw_text.rb +45 -0
- data/lib/walrus/walrus_grammar/ruby_directive.rb +29 -0
- data/lib/walrus/walrus_grammar/ruby_expression.rb +31 -0
- data/lib/walrus/walrus_grammar/set_directive.rb +24 -0
- data/lib/walrus/walrus_grammar/silent_directive.rb +44 -0
- data/lib/walrus/walrus_grammar/slurp_directive.rb +25 -0
- data/lib/walrus/walrus_grammar/super_directive.rb +27 -0
- data/lib/walrus.rb +64 -0
- data/spec/acceptance/acceptance_spec.rb +97 -0
- data/spec/acceptance/block/basic_block.expected +1 -0
- data/spec/acceptance/block/basic_block.tmpl +3 -0
- data/spec/acceptance/block/nested_blocks.expected +5 -0
- data/spec/acceptance/block/nested_blocks.tmpl +11 -0
- data/spec/acceptance/comments/comments_and_text.expected +3 -0
- data/spec/acceptance/comments/comments_and_text.tmpl +6 -0
- data/spec/acceptance/comments/single_comment.expected +0 -0
- data/spec/acceptance/comments/single_comment.tmpl +1 -0
- data/spec/acceptance/def/alternative_def_calling_conventions.expected +3 -0
- data/spec/acceptance/def/alternative_def_calling_conventions.tmpl +18 -0
- data/spec/acceptance/def/basic_def_block_no_output.expected +0 -0
- data/spec/acceptance/def/basic_def_block_no_output.tmpl +17 -0
- data/spec/acceptance/def/defs_can_be_called_multiple_times.expected +3 -0
- data/spec/acceptance/def/defs_can_be_called_multiple_times.tmpl +6 -0
- data/spec/acceptance/def/defs_can_be_dynamic.expected +4 -0
- data/spec/acceptance/def/defs_can_be_dynamic.tmpl +12 -0
- data/spec/acceptance/echo/echo_directive_with_numeric_literal.expected +1 -0
- data/spec/acceptance/echo/echo_directive_with_numeric_literal.tmpl +1 -0
- data/spec/acceptance/echo/echo_expression_list.expected +1 -0
- data/spec/acceptance/echo/echo_expression_list.tmpl +1 -0
- data/spec/acceptance/echo/echo_short_notation.expected +1 -0
- data/spec/acceptance/echo/echo_short_notation.tmpl +1 -0
- data/spec/acceptance/echo/echo_simple_expression.expected +1 -0
- data/spec/acceptance/echo/echo_simple_expression.tmpl +1 -0
- data/spec/acceptance/echo/echo_single_quoted_string_literal.expected +1 -0
- data/spec/acceptance/echo/echo_single_quoted_string_literal.tmpl +1 -0
- data/spec/acceptance/echo/multiple_echo_statements.expected +1 -0
- data/spec/acceptance/echo/multiple_echo_statements.tmpl +2 -0
- data/spec/acceptance/includes/basic_included_file.txt +1 -0
- data/spec/acceptance/includes/basic_includer.complex +3 -0
- data/spec/acceptance/includes/basic_includer.expected +3 -0
- data/spec/acceptance/includes/basic_includer.rb +38 -0
- data/spec/acceptance/includes/complicated_included_file.txt +3 -0
- data/spec/acceptance/includes/complicated_includer.complex +3 -0
- data/spec/acceptance/includes/complicated_includer.expected +3 -0
- data/spec/acceptance/includes/complicated_includer.rb +41 -0
- data/spec/acceptance/includes/nested_include_1.txt +3 -0
- data/spec/acceptance/includes/nested_include_2.txt +1 -0
- data/spec/acceptance/includes/nested_includer.complex +3 -0
- data/spec/acceptance/includes/nested_includer.expected +4 -0
- data/spec/acceptance/includes/nested_includer.rb +41 -0
- data/spec/acceptance/inheritance/basic_child.complex +10 -0
- data/spec/acceptance/inheritance/basic_child.expected +9 -0
- data/spec/acceptance/inheritance/basic_child.rb +54 -0
- data/spec/acceptance/inheritance/basic_parent.complex +5 -0
- data/spec/acceptance/inheritance/basic_parent.expected +3 -0
- data/spec/acceptance/inheritance/basic_parent.rb +41 -0
- data/spec/acceptance/inheritance/importing_child.complex +8 -0
- data/spec/acceptance/inheritance/importing_child.expected +7 -0
- data/spec/acceptance/inheritance/importing_child.rb +46 -0
- data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.complex +8 -0
- data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.expected +7 -0
- data/spec/acceptance/inheritance/subdirectory/importing_child_in_subdirectory.rb +44 -0
- data/spec/acceptance/multiline_comments/multiline_comment_with_directives_inside.expected +0 -0
- data/spec/acceptance/multiline_comments/multiline_comment_with_directives_inside.tmpl +15 -0
- data/spec/acceptance/multiline_comments/simple_multiline_comment.expected +2 -0
- data/spec/acceptance/multiline_comments/simple_multiline_comment.tmpl +4 -0
- data/spec/acceptance/raw/complicated_raw_example.expected +57 -0
- data/spec/acceptance/raw/complicated_raw_example.tmpl +79 -0
- data/spec/acceptance/raw-text/UTF_8.expected +12 -0
- data/spec/acceptance/raw-text/UTF_8.tmpl +12 -0
- data/spec/acceptance/raw-text/empty_file.expected +0 -0
- data/spec/acceptance/raw-text/empty_file.tmpl +0 -0
- data/spec/acceptance/raw-text/multi_line.expected +4 -0
- data/spec/acceptance/raw-text/multi_line.tmpl +4 -0
- data/spec/acceptance/raw-text/single_line.expected +1 -0
- data/spec/acceptance/raw-text/single_line.tmpl +1 -0
- data/spec/acceptance/raw-text/single_line_whitespace.expected +1 -0
- data/spec/acceptance/raw-text/single_line_whitespace.tmpl +1 -0
- data/spec/acceptance/ruby/ruby_directive_is_just_like_silent.expected +1 -0
- data/spec/acceptance/ruby/ruby_directive_is_just_like_silent.tmpl +4 -0
- data/spec/acceptance/ruby/ruby_directive_using_here_doc.expected +1 -0
- data/spec/acceptance/ruby/ruby_directive_using_here_doc.tmpl +4 -0
- data/spec/acceptance/ruby/ruby_directive_using_here_doc_alt_syntax.expected +1 -0
- data/spec/acceptance/ruby/ruby_directive_using_here_doc_alt_syntax.tmpl +4 -0
- data/spec/acceptance/ruby/ruby_directive_with_accumulate.expected +1 -0
- data/spec/acceptance/ruby/ruby_directive_with_accumulate.tmpl +4 -0
- data/spec/acceptance/ruby/ruby_directive_with_accumulate_and_block.expected +1 -0
- data/spec/acceptance/ruby/ruby_directive_with_accumulate_and_block.tmpl +6 -0
- data/spec/acceptance/set/unused_set.expected +0 -0
- data/spec/acceptance/set/unused_set.tmpl +1 -0
- data/spec/acceptance/set/used_set.expected +1 -0
- data/spec/acceptance/set/used_set.tmpl +2 -0
- data/spec/acceptance/silent/silent_and_echo_combined.expected +1 -0
- data/spec/acceptance/silent/silent_and_echo_combined.tmpl +2 -0
- data/spec/acceptance/silent/silent_short_notation.expected +1 -0
- data/spec/acceptance/silent/silent_short_notation.tmpl +1 -0
- data/spec/acceptance/silent/simple_silent_directive.expected +0 -0
- data/spec/acceptance/silent/simple_silent_directive.tmpl +1 -0
- data/spec/acceptance/slurp/basic_slurp_demo.expected +1 -0
- data/spec/acceptance/slurp/basic_slurp_demo.tmpl +4 -0
- data/spec/acceptance/super/super_with_no_effect.expected +4 -0
- data/spec/acceptance/super/super_with_no_effect.tmpl +5 -0
- data/spec/additions/module_spec.rb +126 -0
- data/spec/additions/string_spec.rb +99 -0
- data/spec/compiler_spec.rb +55 -0
- data/spec/grammar/additions/proc_spec.rb +25 -0
- data/spec/grammar/additions/regexp_spec.rb +37 -0
- data/spec/grammar/additions/string_spec.rb +106 -0
- data/spec/grammar/and_predicate_spec.rb +29 -0
- data/spec/grammar/continuation_wrapper_exception_spec.rb +23 -0
- data/spec/grammar/match_data_wrapper_spec.rb +41 -0
- data/spec/grammar/memoizing_cache_spec.rb +112 -0
- data/spec/grammar/node_spec.rb +126 -0
- data/spec/grammar/not_predicate_spec.rb +29 -0
- data/spec/grammar/parser_state_spec.rb +172 -0
- data/spec/grammar/parslet_choice_spec.rb +49 -0
- data/spec/grammar/parslet_combining_spec.rb +287 -0
- data/spec/grammar/parslet_merge_spec.rb +33 -0
- data/spec/grammar/parslet_omission_spec.rb +58 -0
- data/spec/grammar/parslet_repetition_spec.rb +77 -0
- data/spec/grammar/parslet_sequence_spec.rb +49 -0
- data/spec/grammar/parslet_spec.rb +23 -0
- data/spec/grammar/predicate_spec.rb +53 -0
- data/spec/grammar/proc_parslet_spec.rb +52 -0
- data/spec/grammar/regexp_parslet_spec.rb +347 -0
- data/spec/grammar/string_enumerator_spec.rb +94 -0
- data/spec/grammar/string_parslet_spec.rb +143 -0
- data/spec/grammar/symbol_parslet_spec.rb +30 -0
- data/spec/grammar_spec.rb +545 -0
- data/spec/parser_spec.rb +1418 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/walrus_grammar/comment_spec.rb +39 -0
- data/spec/walrus_grammar/echo_directive_spec.rb +63 -0
- data/spec/walrus_grammar/escape_sequence_spec.rb +85 -0
- data/spec/walrus_grammar/literal_spec.rb +41 -0
- data/spec/walrus_grammar/message_expression_spec.rb +37 -0
- data/spec/walrus_grammar/multiline_comment_spec.rb +58 -0
- data/spec/walrus_grammar/placeholder_spec.rb +48 -0
- data/spec/walrus_grammar/raw_directive_spec.rb +81 -0
- data/spec/walrus_grammar/raw_text_spec.rb +65 -0
- data/spec/walrus_grammar/silent_directive_spec.rb +34 -0
- metadata +291 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_choice_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a Parslet Choice' do
|
|
15
|
+
|
|
16
|
+
setup do
|
|
17
|
+
@p1 = 'foo'.to_parseable
|
|
18
|
+
@p2 = 'bar'.to_parseable
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'hashes should be the same if initialized with the same parseables' do
|
|
22
|
+
ParsletChoice.new(@p1, @p2).hash.should == ParsletChoice.new(@p1, @p2).hash
|
|
23
|
+
ParsletChoice.new(@p1, @p2).should eql(ParsletChoice.new(@p1, @p2))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'hashes should (ideally) be different if initialized with different parseables' do
|
|
27
|
+
ParsletChoice.new(@p1, @p2).hash.should_not == ParsletChoice.new('baz'.to_parseable, 'abc'.to_parseable).hash
|
|
28
|
+
ParsletChoice.new(@p1, @p2).should_not eql(ParsletChoice.new('baz'.to_parseable, 'abc'.to_parseable))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'hashes should be different compared to other similar classes even if initialized with the same parseables' do
|
|
32
|
+
ParsletChoice.new(@p1, @p2).hash.should_not == ParsletSequence.new(@p1, @p2).hash
|
|
33
|
+
ParsletChoice.new(@p1, @p2).should_not eql(ParsletSequence.new(@p1, @p2))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should be able to use Parslet Choice instances as keys in a hash' do
|
|
37
|
+
hash = {}
|
|
38
|
+
key1 = ParsletChoice.new(@p1, @p2)
|
|
39
|
+
key2 = ParsletChoice.new('baz'.to_parseable, 'abc'.to_parseable)
|
|
40
|
+
hash[:key1] = 'foo'
|
|
41
|
+
hash[:key2] = 'bar'
|
|
42
|
+
hash[:key1].should == 'foo'
|
|
43
|
+
hash[:key2].should == 'bar'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end # class Grammar
|
|
49
|
+
end # module Walrus
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_combining_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using shorthand operators to combine String, Symbol and Regexp parsers' do
|
|
15
|
+
|
|
16
|
+
it 'should be able to chain a String and a Regexp together' do
|
|
17
|
+
|
|
18
|
+
# try in one order
|
|
19
|
+
sequence = 'foo' & /\d+/
|
|
20
|
+
sequence.parse('foo1000').should == ['foo', '1000']
|
|
21
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError) # first part alone is not enough
|
|
22
|
+
lambda { sequence.parse('1000') }.should raise_error(ParseError) # neither is second part alone
|
|
23
|
+
lambda { sequence.parse('1000foo') }.should raise_error(ParseError) # order matters
|
|
24
|
+
|
|
25
|
+
# same test but in reverse order
|
|
26
|
+
sequence = /\d+/ & 'foo'
|
|
27
|
+
sequence.parse('1000foo').should == ['1000', 'foo']
|
|
28
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError) # first part alone is not enough
|
|
29
|
+
lambda { sequence.parse('1000') }.should raise_error(ParseError) # neither is second part alone
|
|
30
|
+
lambda { sequence.parse('foo1000') }.should raise_error(ParseError) # order matters
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'should be able to choose between a String and a Regexp' do
|
|
35
|
+
|
|
36
|
+
# try in one order
|
|
37
|
+
sequence = 'foo' | /\d+/
|
|
38
|
+
sequence.parse('foo').should == 'foo'
|
|
39
|
+
sequence.parse('100').should == '100'
|
|
40
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
41
|
+
|
|
42
|
+
# same test but in reverse order
|
|
43
|
+
sequence = /\d+/ | 'foo'
|
|
44
|
+
sequence.parse('foo').should == 'foo'
|
|
45
|
+
sequence.parse('100').should == '100'
|
|
46
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should be able to freely intermix String and Regexp objects when chaining and choosing' do
|
|
51
|
+
|
|
52
|
+
sequence = 'foo' & /\d+/ | 'bar' & /[XYZ]{3}/
|
|
53
|
+
sequence.parse('foo123').should == ['foo', '123']
|
|
54
|
+
sequence.parse('barZYX').should == ['bar', 'ZYX']
|
|
55
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
56
|
+
lambda { sequence.parse('123') }.should raise_error(ParseError)
|
|
57
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
58
|
+
lambda { sequence.parse('XYZ') }.should raise_error(ParseError)
|
|
59
|
+
lambda { sequence.parse('barXY') }.should raise_error(ParseError)
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should be able to specify minimum and maximum repetition using shorthand methods' do
|
|
64
|
+
|
|
65
|
+
# optional (same as "?" in regular expressions)
|
|
66
|
+
sequence = 'foo'.optional
|
|
67
|
+
sequence.parse('foo').should == 'foo'
|
|
68
|
+
lambda { sequence.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess)
|
|
69
|
+
|
|
70
|
+
# zero_or_one (same as optional; "?" in regular expressions)
|
|
71
|
+
sequence = 'foo'.zero_or_one
|
|
72
|
+
sequence.parse('foo').should == 'foo'
|
|
73
|
+
lambda { sequence.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess)
|
|
74
|
+
|
|
75
|
+
# zero_or_more (same as "*" in regular expressions)
|
|
76
|
+
sequence = 'foo'.zero_or_more
|
|
77
|
+
sequence.parse('foo').should == 'foo'
|
|
78
|
+
sequence.parse('foofoofoobar').should == ['foo', 'foo', 'foo']
|
|
79
|
+
lambda { sequence.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess)
|
|
80
|
+
|
|
81
|
+
# one_or_more (same as "+" in regular expressions)
|
|
82
|
+
sequence = 'foo'.one_or_more
|
|
83
|
+
sequence.parse('foo').should == 'foo'
|
|
84
|
+
sequence.parse('foofoofoobar').should == ['foo', 'foo', 'foo']
|
|
85
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
86
|
+
|
|
87
|
+
# repeat (arbitary limits for min, max; same as {min, max} in regular expressions)
|
|
88
|
+
sequence = 'foo'.repeat(3, 5)
|
|
89
|
+
sequence.parse('foofoofoobar').should == ['foo', 'foo', 'foo']
|
|
90
|
+
sequence.parse('foofoofoofoobar').should == ['foo', 'foo', 'foo', 'foo']
|
|
91
|
+
sequence.parse('foofoofoofoofoobar').should == ['foo', 'foo', 'foo', 'foo', 'foo']
|
|
92
|
+
sequence.parse('foofoofoofoofoofoobar').should == ['foo', 'foo', 'foo', 'foo', 'foo']
|
|
93
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
94
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
95
|
+
lambda { sequence.parse('foofoo') }.should raise_error(ParseError)
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'should be able to apply repetitions to other combinations wrapped in parentheses' do
|
|
100
|
+
sequence = ('foo' & 'bar').one_or_more
|
|
101
|
+
sequence.parse('foobar').should == ['foo', 'bar']
|
|
102
|
+
sequence.parse('foobarfoobar').should == [['foo', 'bar'], ['foo', 'bar']] # fails: just returns ['foo', 'bar']
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should be able to combine use of repetition shorthand methods with other shorthand methods' do
|
|
106
|
+
|
|
107
|
+
# first we test with chaining
|
|
108
|
+
sequence = 'foo'.optional & 'bar' & 'abc'.one_or_more
|
|
109
|
+
sequence.parse('foobarabc').should == ['foo', 'bar', 'abc']
|
|
110
|
+
sequence.parse('foobarabcabc').should == ['foo', 'bar', ['abc', 'abc']]
|
|
111
|
+
sequence.parse('barabc').should == ['bar', 'abc']
|
|
112
|
+
lambda { sequence.parse('abc') }.should raise_error(ParseError)
|
|
113
|
+
|
|
114
|
+
# similar test but with alternation
|
|
115
|
+
sequence = 'foo' | 'bar' | 'abc'.one_or_more
|
|
116
|
+
sequence.parse('foobarabc').should == 'foo'
|
|
117
|
+
sequence.parse('barabc').should == 'bar'
|
|
118
|
+
sequence.parse('abc').should == 'abc'
|
|
119
|
+
sequence.parse('abcabc').should == ['abc', 'abc']
|
|
120
|
+
lambda { sequence.parse('nothing') }.should raise_error(ParseError)
|
|
121
|
+
|
|
122
|
+
# test with defective sequence (makes no sense to use "optional" with alternation, will always succeed)
|
|
123
|
+
sequence = 'foo'.optional | 'bar' | 'abc'.one_or_more
|
|
124
|
+
sequence.parse('foobarabc').should == 'foo'
|
|
125
|
+
lambda { sequence.parse('nothing') }.should throw_symbol(:ZeroWidthParseSuccess)
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'should be able to chain a "not predicate"' do
|
|
130
|
+
sequence = 'foo' & 'bar'.not!
|
|
131
|
+
sequence.parse('foo').should == 'foo' # fails with ['foo'] because that's the way ParserState works...
|
|
132
|
+
sequence.parse('foo...').should == 'foo' # same
|
|
133
|
+
lambda { sequence.parse('foobar') }.should raise_error(ParseError)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'an isolated "not predicate" should return a zero-width match' do
|
|
137
|
+
sequence = 'foo'.not!
|
|
138
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
139
|
+
lambda { sequence.parse('bar') }.should throw_symbol(:NotPredicateSuccess)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it 'two "not predicates" chained together should act like a union' do
|
|
143
|
+
|
|
144
|
+
# this means "not followed by 'foo' and not followed by 'bar'"
|
|
145
|
+
sequence = 'foo'.not! & 'bar'.not!
|
|
146
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
147
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
148
|
+
lambda { sequence.parse('abc') }.should throw_symbol(:NotPredicateSuccess)
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it 'should be able to chain an "and predicate"' do
|
|
153
|
+
sequence = 'foo' & 'bar'.and?
|
|
154
|
+
sequence.parse('foobar').should == 'foo' # same problem, returns ['foo']
|
|
155
|
+
lambda { sequence.parse('foo...') }.should raise_error(ParseError)
|
|
156
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'an isolated "and predicate" should return a zero-width match' do
|
|
160
|
+
sequence = 'foo'.and?
|
|
161
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
162
|
+
lambda { sequence.parse('foo') }.should throw_symbol(:AndPredicateSuccess)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it 'should be able to follow an "and predicate" with other parslets or combinations' do
|
|
166
|
+
|
|
167
|
+
# this is equivalent to "foo" if followed by "bar", or any three characters
|
|
168
|
+
sequence = 'foo' & 'bar'.and? | /.../
|
|
169
|
+
sequence.parse('foobar').should == 'foo' # returns ['foo']
|
|
170
|
+
sequence.parse('abc').should == 'abc'
|
|
171
|
+
lambda { sequence.parse('') }.should raise_error(ParseError)
|
|
172
|
+
|
|
173
|
+
# it makes little sense for the predicate to follows a choice operator so we don't test that
|
|
174
|
+
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'should be able to follow a "not predicate" with other parslets or combinations' do
|
|
178
|
+
|
|
179
|
+
# this is equivalent to "foo" followed by any three characters other than "bar"
|
|
180
|
+
sequence = 'foo' & 'bar'.not! & /.../
|
|
181
|
+
sequence.parse('fooabc').should == ['foo', 'abc']
|
|
182
|
+
lambda { sequence.parse('foobar') }.should raise_error(ParseError)
|
|
183
|
+
lambda { sequence.parse('foo') }.should raise_error(ParseError)
|
|
184
|
+
lambda { sequence.parse('') }.should raise_error(ParseError)
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
it 'should be able to include a "not predicate" when using a repetition operator' do
|
|
189
|
+
|
|
190
|
+
# basic example
|
|
191
|
+
sequence = ('foo' & 'bar'.not!).one_or_more
|
|
192
|
+
sequence.parse('foo').should == 'foo'
|
|
193
|
+
sequence.parse('foofoobar').should == 'foo'
|
|
194
|
+
sequence.parse('foofoo').should == ['foo', 'foo']
|
|
195
|
+
lambda { sequence.parse('bar') }.should raise_error(ParseError)
|
|
196
|
+
lambda { sequence.parse('foobar') }.should raise_error(ParseError)
|
|
197
|
+
|
|
198
|
+
# variation: note that greedy matching alters the behaviour
|
|
199
|
+
sequence = ('foo' & 'bar').one_or_more & 'abc'.not!
|
|
200
|
+
sequence.parse('foobar').should == ['foo', 'bar']
|
|
201
|
+
sequence.parse('foobarfoobar').should == [['foo', 'bar'], ['foo', 'bar']]
|
|
202
|
+
lambda { sequence.parse('foobarabc') }.should raise_error(ParseError)
|
|
203
|
+
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'should be able to use regular expression shortcuts in conjunction with predicates' do
|
|
207
|
+
|
|
208
|
+
# match "foo" as long as it's not followed by a digit
|
|
209
|
+
sequence = 'foo' & /\d/.not!
|
|
210
|
+
sequence.parse('foo').should == 'foo'
|
|
211
|
+
sequence.parse('foobar').should == 'foo'
|
|
212
|
+
lambda { sequence.parse('foo1') }.should raise_error(ParseError)
|
|
213
|
+
|
|
214
|
+
# match "word" characters as long as they're not followed by whitespace
|
|
215
|
+
sequence = /\w+/ & /\s/.not!
|
|
216
|
+
sequence.parse('foo').should == 'foo'
|
|
217
|
+
lambda { sequence.parse('foo ') }.should raise_error(ParseError)
|
|
218
|
+
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
describe 'omitting tokens from the output using the "skip" method' do
|
|
224
|
+
|
|
225
|
+
it 'should be able to skip quotation marks delimiting a string' do
|
|
226
|
+
sequence = '"'.skip & /[^"]+/ & '"'.skip
|
|
227
|
+
sequence.parse('"hello world"').should == 'hello world' # note this is returning a ParserState object
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it 'should be able to skip within a repetition expression' do
|
|
231
|
+
sequence = ('foo'.skip & /\d+/).one_or_more
|
|
232
|
+
sequence.parse('foo1...').should == '1'
|
|
233
|
+
sequence.parse('foo1foo2...').should == ['1', '2'] # only returns 1
|
|
234
|
+
sequence.parse('foo1foo2foo3...').should == ['1', '2', '3'] # only returns 1
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
it 'should be able to skip commas separating a list' do
|
|
238
|
+
|
|
239
|
+
# closer to real-world use: a comma-separated list
|
|
240
|
+
sequence = /\w+/ & (/\s*,\s*/.skip & /\w+/).zero_or_more
|
|
241
|
+
sequence.parse('a').should == 'a'
|
|
242
|
+
sequence.parse('a, b').should == ['a', 'b']
|
|
243
|
+
sequence.parse('a, b, c').should == ['a', ['b', 'c']]
|
|
244
|
+
sequence.parse('a, b, c, d').should == ['a', ['b', 'c', 'd']]
|
|
245
|
+
|
|
246
|
+
# again, using the ">>" operator
|
|
247
|
+
sequence = /\w+/ >> (/\s*,\s*/.skip & /\w+/).zero_or_more
|
|
248
|
+
sequence.parse('a').should == 'a'
|
|
249
|
+
sequence.parse('a, b').should == ['a', 'b']
|
|
250
|
+
sequence.parse('a, b, c').should == ['a', 'b', 'c']
|
|
251
|
+
sequence.parse('a, b, c, d').should == ['a', 'b', 'c', 'd']
|
|
252
|
+
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe 'using the shorthand ">>" pseudo-operator' do
|
|
258
|
+
|
|
259
|
+
it 'should be able to chain the operator multiple times' do
|
|
260
|
+
|
|
261
|
+
# comma-separated words followed by comma-separated digits
|
|
262
|
+
sequence = /[a-zA-Z]+/ >> (/\s*,\s*/.skip & /[a-zA-Z]+/).zero_or_more >> (/\s*,\s*/.skip & /\d+/).one_or_more
|
|
263
|
+
sequence.parse('a, 1').should == ['a', '1']
|
|
264
|
+
sequence.parse('a, b, 1').should == ['a', 'b', '1']
|
|
265
|
+
sequence.parse('a, 1, 2').should == ['a', '1', '2']
|
|
266
|
+
sequence.parse('a, b, 1, 2').should == ['a', 'b', '1', '2']
|
|
267
|
+
|
|
268
|
+
# same, but enclosed in quotes
|
|
269
|
+
sequence = '"'.skip & /[a-zA-Z]+/ >> (/\s*,\s*/.skip & /[a-zA-Z]+/).zero_or_more >> (/\s*,\s*/.skip & /\d+/).one_or_more & '"'.skip
|
|
270
|
+
sequence.parse('"a, 1"').should == ['a', '1']
|
|
271
|
+
sequence.parse('"a, b, 1"').should == ['a', 'b', '1']
|
|
272
|
+
sequence.parse('"a, 1, 2"').should == ['a', '1', '2']
|
|
273
|
+
sequence.parse('"a, b, 1, 2"').should == ['a', 'b', '1', '2']
|
|
274
|
+
|
|
275
|
+
# alternative construction of same
|
|
276
|
+
sequence = /[a-zA-Z]+/ >> (/\s*,\s*/.skip & /[a-zA-Z]+/).zero_or_more & /\s*,\s*/.skip & /\d+/ >> (/\s*,\s*/.skip & /\d+/).zero_or_more
|
|
277
|
+
sequence.parse('a, 1').should == ['a', '1']
|
|
278
|
+
sequence.parse('a, b, 1').should == ['a', 'b', '1']
|
|
279
|
+
sequence.parse('a, 1, 2').should == ['a', '1', '2']
|
|
280
|
+
sequence.parse('a, b, 1, 2').should == ['a', 'b', '1', '2']
|
|
281
|
+
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
end # class Grammar
|
|
287
|
+
end # module Walrus
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_merge_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a Parslet Merge' do
|
|
15
|
+
|
|
16
|
+
it 'should be able to compare for equality' do
|
|
17
|
+
ParsletMerge.new('foo', 'bar').should eql(ParsletMerge.new('foo', 'bar'))
|
|
18
|
+
ParsletMerge.new('foo', 'bar').should_not eql(ParsletOmission.new('foo')) # wrong class
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'ParsletMerge and ParsletSequence hashs should not match even if created using the same parseable instances' do
|
|
22
|
+
parseable1 = 'foo'.to_parseable
|
|
23
|
+
parseable2 = 'bar'.to_parseable
|
|
24
|
+
p1 = ParsletMerge.new(parseable1, parseable2)
|
|
25
|
+
p2 = ParsletSequence.new(parseable1, parseable2)
|
|
26
|
+
p1.hash.should_not == p2.hash
|
|
27
|
+
p1.should_not eql(p2)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # class Grammar
|
|
33
|
+
end # module Walrus
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_omission_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a Parslet Omission' do
|
|
15
|
+
|
|
16
|
+
it 'should raise if "parseable" argument is nil' do
|
|
17
|
+
lambda { ParsletOmission.new(nil) }.should raise_error(ArgumentError)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should complain if pass nil string for parsing' do
|
|
21
|
+
lambda { ParsletOmission.new('foo'.to_parseable).parse(nil) }.should raise_error(ArgumentError)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should let parse errors from lower levels fall through' do
|
|
25
|
+
lambda { ParsletOmission.new('foo'.to_parseable).parse('bar') }.should raise_error(ParseError)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should indicate parse errors with a SubstringSkippedException' do
|
|
29
|
+
lambda { ParsletOmission.new('foo'.to_parseable).parse('foo') }.should raise_error(SkippedSubstringException)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'the raised SubstringSkippedException should include the parsed substring' do
|
|
33
|
+
begin
|
|
34
|
+
ParsletOmission.new('foo'.to_parseable).parse('foobar')
|
|
35
|
+
rescue SkippedSubstringException => e
|
|
36
|
+
substring = e.to_s
|
|
37
|
+
end
|
|
38
|
+
substring.should == 'foo'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'the parsed substring should be an empty string in the case of a zero-width parse success at a lower level' do
|
|
42
|
+
begin
|
|
43
|
+
ParsletOmission.new('foo'.optional).parse('bar') # a contrived example
|
|
44
|
+
rescue SkippedSubstringException => e
|
|
45
|
+
substring = e.to_s
|
|
46
|
+
end
|
|
47
|
+
substring.should == ''
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'should be able to compare for equality' do
|
|
51
|
+
ParsletOmission.new('foo').should eql(ParsletOmission.new('foo'))
|
|
52
|
+
ParsletOmission.new('foo').should_not eql(ParsletOmission.new('bar'))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end # class Grammar
|
|
58
|
+
end # module Walrus
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_repetition_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a Parslet Repetition' do
|
|
15
|
+
|
|
16
|
+
it 'should raise if "parseable" argument is nil' do
|
|
17
|
+
lambda { ParsletRepetition.new(nil, 0) }.should raise_error(ArgumentError)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should raise if "min" argument is nil' do
|
|
21
|
+
lambda { ParsletRepetition.new('foo'.to_parseable, nil) }.should raise_error(ArgumentError)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'should raise if pass nil string for parsing' do
|
|
25
|
+
lambda { ParsletRepetition.new('foo'.to_parseable, 0).parse(nil) }.should raise_error(ArgumentError)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should be able to match "zero or more" times (like "*" in regular expressions)' do
|
|
29
|
+
parslet = ParsletRepetition.new('foo'.to_parseable, 0)
|
|
30
|
+
lambda { parslet.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess) # zero times
|
|
31
|
+
parslet.parse('foo').should == 'foo' # one time
|
|
32
|
+
parslet.parse('foofoo').should == ['foo', 'foo'] # two times
|
|
33
|
+
parslet.parse('foofoofoobar').should == ['foo', 'foo', 'foo'] # three times
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should be able to match "zero or one" times (like "?" in regular expressions)' do
|
|
37
|
+
parslet = ParsletRepetition.new('foo'.to_parseable, 0, 1)
|
|
38
|
+
lambda { parslet.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess) # zero times
|
|
39
|
+
parslet.parse('foo').should == 'foo' # one time
|
|
40
|
+
parslet.parse('foofoo').should == 'foo' # stop at one time
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should be able to match "one or more" times (like "+" in regular expressions)' do
|
|
44
|
+
parslet = ParsletRepetition.new('foo'.to_parseable, 1)
|
|
45
|
+
lambda { parslet.parse('bar') }.should raise_error(ParseError) # zero times (error)
|
|
46
|
+
parslet.parse('foo').should == 'foo' # one time
|
|
47
|
+
parslet.parse('foofoo').should == ['foo', 'foo'] # two times
|
|
48
|
+
parslet.parse('foofoofoobar').should == ['foo', 'foo', 'foo'] # three times
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should be able to match "between X and Y" times (like {X, Y} in regular expressions)' do
|
|
52
|
+
parslet = ParsletRepetition.new('foo'.to_parseable, 2, 3)
|
|
53
|
+
lambda { parslet.parse('bar') }.should raise_error(ParseError) # zero times (error)
|
|
54
|
+
lambda { parslet.parse('foo') }.should raise_error(ParseError) # one time (error)
|
|
55
|
+
parslet.parse('foofoo').should == ['foo', 'foo'] # two times
|
|
56
|
+
parslet.parse('foofoofoo').should == ['foo', 'foo', 'foo'] # three times
|
|
57
|
+
parslet.parse('foofoofoofoo').should == ['foo', 'foo', 'foo'] # stop at three times
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'matches should be greedy' do
|
|
61
|
+
|
|
62
|
+
# here the ParsletRepetition should consume all the "foos", leaving nothing for the final parslet
|
|
63
|
+
parslet = ParsletRepetition.new('foo'.to_parseable, 1) & 'foo'
|
|
64
|
+
lambda { parslet.parse('foofoofoofoo') }.should raise_error(ParseError)
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should be able to compare for equality' do
|
|
69
|
+
ParsletRepetition.new('foo'.to_parseable, 1).should eql(ParsletRepetition.new('foo'.to_parseable, 1))
|
|
70
|
+
ParsletRepetition.new('foo'.to_parseable, 1).should_not eql(ParsletRepetition.new('bar'.to_parseable, 1))
|
|
71
|
+
ParsletRepetition.new('foo'.to_parseable, 1).should_not eql(ParsletRepetition.new('foo'.to_parseable, 2))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end # class Grammar
|
|
77
|
+
end # module Walrus
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_sequence_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a Parslet Sequence' do
|
|
15
|
+
|
|
16
|
+
setup do
|
|
17
|
+
@p1 = 'foo'.to_parseable
|
|
18
|
+
@p2 = 'bar'.to_parseable
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'hashes should be the same if initialized with the same parseables' do
|
|
22
|
+
ParsletSequence.new(@p1, @p2).hash.should == ParsletSequence.new(@p1, @p2).hash
|
|
23
|
+
ParsletSequence.new(@p1, @p2).should eql(ParsletSequence.new(@p1, @p2))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'hashes should (ideally) be different if initialized with different parseables' do
|
|
27
|
+
ParsletSequence.new(@p1, @p2).hash.should_not == ParsletSequence.new('baz'.to_parseable, 'abc'.to_parseable).hash
|
|
28
|
+
ParsletSequence.new(@p1, @p2).should_not eql(ParsletSequence.new('baz'.to_parseable, 'abc'.to_parseable))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'hashes should be different compared to other similar classes even if initialized with the same parseables' do
|
|
32
|
+
ParsletSequence.new(@p1, @p2).hash.should_not == ParsletChoice.new(@p1, @p2).hash
|
|
33
|
+
ParsletSequence.new(@p1, @p2).should_not eql(ParsletChoice.new(@p1, @p2))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should be able to use Parslet Choice instances as keys in a hash' do
|
|
37
|
+
hash = {}
|
|
38
|
+
key1 = ParsletSequence.new(@p1, @p2)
|
|
39
|
+
key2 = ParsletSequence.new('baz'.to_parseable, 'abc'.to_parseable)
|
|
40
|
+
hash[:key1] = 'foo'
|
|
41
|
+
hash[:key2] = 'bar'
|
|
42
|
+
hash[:key1].should == 'foo'
|
|
43
|
+
hash[:key2].should == 'bar'
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end # class Grammar
|
|
49
|
+
end # module Walrus
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/parslet_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
describe 'using a parslet' do
|
|
15
|
+
|
|
16
|
+
it 'should complain if sent "parse" message (Parslet is an abstract superclass, "parse" is the responsibility of the subclasses)' do
|
|
17
|
+
lambda { Parslet.new.parse('bar') }.should raise_error(NotImplementedError)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class Grammar
|
|
23
|
+
end # module Walrus
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Copyright 2007 Wincent Colaiuta
|
|
2
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
3
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
4
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
5
|
+
# in the accompanying file, "LICENSE.txt", for more details.
|
|
6
|
+
#
|
|
7
|
+
# $Id: /mirrors/Walrus/trunk/walrus/spec/grammar/predicate_spec.rb 6702 2007-04-09T15:04:40.448669Z wincent $
|
|
8
|
+
|
|
9
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
10
|
+
|
|
11
|
+
module Walrus
|
|
12
|
+
class Grammar
|
|
13
|
+
|
|
14
|
+
autoload(:AndPredicate, 'walrus/grammar/and_predicate')
|
|
15
|
+
autoload(:NotPredicate, 'walrus/grammar/not_predicate')
|
|
16
|
+
|
|
17
|
+
describe 'using a predicate' do
|
|
18
|
+
|
|
19
|
+
it 'should raise an ArgumentError if initialized with nil' do
|
|
20
|
+
lambda { Predicate.new(nil) }.should raise_error(ArgumentError)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should complain if sent "parse" message (Predicate abstract superclass, "parse" is the responsibility of the subclasses)' do
|
|
24
|
+
lambda { Predicate.new('foo').parse('bar') }.should raise_error(NotImplementedError)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'should be able to compare predicates for equality' do
|
|
28
|
+
Predicate.new('foo').should eql(Predicate.new('foo'))
|
|
29
|
+
Predicate.new('foo').should_not eql(Predicate.new('bar'))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it '"and" and "not" predicates should yield different hashes even if initialized with the same "parseable"' do
|
|
33
|
+
|
|
34
|
+
parseable = 'foo'.to_parseable
|
|
35
|
+
p1 = Predicate.new(parseable)
|
|
36
|
+
p2 = AndPredicate.new(parseable)
|
|
37
|
+
p3 = NotPredicate.new(parseable)
|
|
38
|
+
|
|
39
|
+
p1.hash.should_not == p2.hash
|
|
40
|
+
p2.hash.should_not == p3.hash
|
|
41
|
+
p3.hash.should_not == p1.hash
|
|
42
|
+
|
|
43
|
+
p1.should_not eql(p2)
|
|
44
|
+
p2.should_not eql(p3)
|
|
45
|
+
p3.should_not eql(p1)
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end # class Grammar
|
|
53
|
+
end # module Walrus
|