citrus 1.0.0

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.
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class AndPredicateTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = AndPredicate.new
7
+ assert_equal(false, rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = AndPredicate.new('a')
12
+
13
+ match = rule.match(input('b'))
14
+ assert_equal(nil, match)
15
+
16
+ match = rule.match(input('a'))
17
+ assert(match)
18
+ assert_equal('', match.text)
19
+ assert_equal(0, match.length)
20
+ end
21
+
22
+ def test_to_s
23
+ rule = AndPredicate.new('a')
24
+ assert_equal('&"a"', rule.to_s)
25
+ end
26
+
27
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ Citrus.load(File.dirname(__FILE__) + '/../examples/calc')
3
+
4
+ class CalcPEGTest < Test::Unit::TestCase
5
+ include CalcTests
6
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require File.dirname(__FILE__) + '/../examples/calc_sugar'
3
+
4
+ class CalcSugarTest < Test::Unit::TestCase
5
+ include CalcTests
6
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require File.dirname(__FILE__) + '/../examples/calc'
3
+
4
+ class CalcTest < Test::Unit::TestCase
5
+ include CalcTests
6
+ end
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ChoiceTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = Choice.new
7
+ assert_equal(false, rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = Choice.new(%w<a b>)
12
+
13
+ match = rule.match(input(''))
14
+ assert_equal(nil, match)
15
+
16
+ match = rule.match(input('a'))
17
+ assert(match)
18
+ assert_equal('a', match.text)
19
+ assert_equal(1, match.length)
20
+ end
21
+
22
+ def test_match_multi
23
+ rule = Choice.new(%w<a b>)
24
+
25
+ match = rule.match(input('ab'))
26
+ assert(match)
27
+ assert_equal('a', match.text)
28
+ assert_equal(1, match.length)
29
+
30
+ match = rule.match(input('ba'))
31
+ assert(match)
32
+ assert_equal('b', match.text)
33
+ assert_equal(1, match.length)
34
+ end
35
+
36
+ def test_match_embed
37
+ rule = Choice.new([ /\d+/, Choice.new(%w<+ ->) ])
38
+
39
+ match = rule.match(input('1+'))
40
+ assert(match)
41
+ assert_equal('1', match.text)
42
+ assert_equal(1, match.length)
43
+
44
+ match = rule.match(input('+1'))
45
+ assert(match)
46
+ assert_equal('+', match.text)
47
+ assert_equal(1, match.length)
48
+ end
49
+
50
+ def test_to_s
51
+ rule = Choice.new(%w<a b>)
52
+ assert_equal('"a" | "b"', rule.to_s)
53
+ end
54
+
55
+ def test_to_s_embed
56
+ rule1 = Choice.new(%w<a b>)
57
+ rule2 = Choice.new(%w<c d>)
58
+ rule = Choice.new([rule1, rule2])
59
+ assert_equal('("a" | "b") | ("c" | "d")', rule.to_s)
60
+ end
61
+
62
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ExpressionTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = Expression.new
7
+ assert(rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = Expression.new(/\d+/)
12
+ match = rule.match(input('123 456'))
13
+ assert(match)
14
+ assert_equal('123', match.text)
15
+ assert_equal(3, match.length)
16
+ end
17
+
18
+ def test_match_failure
19
+ rule = Expression.new(/\d+/)
20
+ match = rule.match(input(' 456'))
21
+ assert_equal(nil, match)
22
+ end
23
+
24
+ def test_to_s
25
+ rule = Expression.new(/\d+/)
26
+ assert_equal('/\\d+/', rule.to_s)
27
+ end
28
+
29
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class FixedWidthTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = FixedWidth.new
7
+ assert(rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = FixedWidth.new('abc')
12
+ match = rule.match(input('abc'))
13
+ assert(match)
14
+ assert_equal('abc', match.text)
15
+ assert_equal(3, match.length)
16
+ end
17
+
18
+ def test_match_short
19
+ rule = FixedWidth.new('abc')
20
+ match = rule.match(input('ab'))
21
+ assert_equal(nil, match)
22
+ end
23
+
24
+ def test_match_long
25
+ rule = FixedWidth.new('abc')
26
+ match = rule.match(input('abcd'))
27
+ assert(match)
28
+ assert_equal('abc', match.text)
29
+ assert_equal(3, match.length)
30
+ end
31
+
32
+ def test_to_s
33
+ rule = FixedWidth.new('abc')
34
+ assert_equal('"abc"', rule.to_s)
35
+ end
36
+
37
+ end
@@ -0,0 +1,129 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class GrammarTest < Test::Unit::TestCase
4
+
5
+ def test_new
6
+ Grammar.new do |g|
7
+ assert_kind_of(Module, g)
8
+ assert(g.include?(Grammar))
9
+ end
10
+ end
11
+
12
+ def test_name
13
+ assert_equal("Test::Unit::TestCase::TestGrammar", TestGrammar.name)
14
+ end
15
+
16
+ def test_no_name
17
+ grammar = Grammar.new
18
+ assert_equal('', grammar.name)
19
+ end
20
+
21
+ def test_rule_names
22
+ assert_equal([:alpha, :num, :alphanum], TestGrammar.rule_names)
23
+ end
24
+
25
+ def test_has_name
26
+ assert(TestGrammar.has_rule?('alpha'))
27
+ assert(TestGrammar.has_rule?(:alpha))
28
+ end
29
+
30
+ def test_doesnt_have_name
31
+ assert_equal(false, TestGrammar.has_rule?(:value))
32
+ end
33
+
34
+ def test_parse_fixed_width
35
+ grammar = Grammar.new {
36
+ rule(:abc) { 'abc' }
37
+ }
38
+ match = grammar.parse('abc')
39
+ assert(match)
40
+ assert_equal('abc', match.text)
41
+ assert_equal(3, match.length)
42
+ end
43
+
44
+ def test_parse_expression
45
+ grammar = Grammar.new {
46
+ rule(:alpha) { /[a-z]+/i }
47
+ }
48
+ match = grammar.parse('abc')
49
+ assert(match)
50
+ assert_equal('abc', match.text)
51
+ assert_equal(3, match.length)
52
+ end
53
+
54
+ def test_parse_sequence
55
+ grammar = Grammar.new {
56
+ rule(:num) { all(1, 2, 3) }
57
+ }
58
+ match = grammar.parse('123')
59
+ assert(match)
60
+ assert_equal('123', match.text)
61
+ assert_equal(3, match.length)
62
+ end
63
+
64
+ def test_parse_sequence_long
65
+ grammar = Grammar.new {
66
+ rule(:num) { all(1, 2, 3) }
67
+ }
68
+ assert_raise ParseError do
69
+ match = grammar.parse('1234')
70
+ end
71
+ end
72
+
73
+ def test_parse_sequence_short
74
+ grammar = Grammar.new {
75
+ rule(:num) { all(1, 2, 3) }
76
+ }
77
+ assert_raise ParseError do
78
+ match = grammar.parse('12')
79
+ end
80
+ end
81
+
82
+ def test_parse_choice
83
+ grammar = Grammar.new {
84
+ rule(:alphanum) { any(/[a-z]/i, 0..9) }
85
+ }
86
+
87
+ match = grammar.parse('a')
88
+ assert(match)
89
+ assert_equal('a', match.text)
90
+ assert_equal(1, match.length)
91
+
92
+ match = grammar.parse('1')
93
+ assert(match)
94
+ assert_equal('1', match.text)
95
+ assert_equal(1, match.length)
96
+ end
97
+
98
+ def test_parse_choice_miss
99
+ grammar = Grammar.new {
100
+ rule(:alphanum) { any(/[a-z]/, 0..9) }
101
+ }
102
+ assert_raise ParseError do
103
+ match = grammar.parse('A')
104
+ end
105
+ end
106
+
107
+ def test_parse_recurs
108
+ grammar = Grammar.new {
109
+ rule(:paren) { any(['(', :paren, ')'], /[a-z]/) }
110
+ }
111
+
112
+ match = grammar.parse('a')
113
+ assert(match)
114
+ assert_equal('a', match.text)
115
+ assert_equal(1, match.length)
116
+
117
+ match = grammar.parse('((a))')
118
+ assert(match)
119
+ assert('((a))', match.text)
120
+ assert(5, match.length)
121
+
122
+ str = ('(' * 200) + 'a' + (')' * 200)
123
+ match = grammar.parse(str)
124
+ assert(match)
125
+ assert(str, match.text)
126
+ assert(str.length, match.length)
127
+ end
128
+
129
+ end
@@ -0,0 +1,143 @@
1
+ lib = File.expand_path('../../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'test/unit'
5
+ require 'citrus/debug'
6
+
7
+ class Test::Unit::TestCase
8
+ include Citrus
9
+
10
+ def input(str='')
11
+ Input.new(str)
12
+ end
13
+
14
+ module TestGrammar
15
+ include Citrus::Grammar
16
+
17
+ rule :alpha do
18
+ /[a-zA-Z]/
19
+ end
20
+
21
+ rule :num do
22
+ ext(/[0-9]/) {
23
+ def value
24
+ text.to_i
25
+ end
26
+ }
27
+ end
28
+
29
+ rule :alphanum do
30
+ any(:alpha, :num)
31
+ end
32
+ end
33
+
34
+ class EqualRule
35
+ include Citrus::Rule
36
+
37
+ def initialize(value)
38
+ @value = value
39
+ end
40
+
41
+ def match(input, offset=0)
42
+ create_match(@value.to_s.dup, offset) if @value.to_s == input.string
43
+ end
44
+ end
45
+
46
+ module CalcTests
47
+ def test_int
48
+ match = Calc.parse('3')
49
+ assert(match)
50
+ assert_equal('3', match.text)
51
+ assert_equal(1, match.length)
52
+ assert_equal(3, match.value)
53
+ end
54
+
55
+ def test_float
56
+ match = Calc.parse('1.5')
57
+ assert(match)
58
+ assert_equal('1.5', match.text)
59
+ assert_equal(3, match.length)
60
+ assert_equal(1.5, match.value)
61
+ end
62
+
63
+ def test_addition
64
+ match = Calc.parse('1+2')
65
+ assert(match)
66
+ assert_equal('1+2', match.text)
67
+ assert_equal(3, match.length)
68
+ assert_equal(3, match.value)
69
+ end
70
+
71
+ def test_addition_multi
72
+ match = Calc.parse('1+2+3')
73
+ assert(match)
74
+ assert_equal('1+2+3', match.text)
75
+ assert_equal(5, match.length)
76
+ assert_equal(6, match.value)
77
+ end
78
+
79
+ def test_addition_float
80
+ match = Calc.parse('1.5+3')
81
+ assert(match)
82
+ assert_equal('1.5+3', match.text)
83
+ assert_equal(5, match.length)
84
+ assert_equal(4.5, match.value)
85
+ end
86
+
87
+ def test_subtraction
88
+ match = Calc.parse('3-2')
89
+ assert(match)
90
+ assert_equal(1, match.value)
91
+ end
92
+
93
+ def test_subtraction_float
94
+ match = Calc.parse('4.5-3')
95
+ assert(match)
96
+ assert_equal('4.5-3', match.text)
97
+ assert_equal(5, match.length)
98
+ assert_equal(1.5, match.value)
99
+ end
100
+
101
+ def test_multiplication
102
+ match = Calc.parse('2*5')
103
+ assert(match)
104
+ assert_equal(10, match.value)
105
+ end
106
+
107
+ def test_multiplication_float
108
+ match = Calc.parse('1.5*3')
109
+ assert(match)
110
+ assert_equal('1.5*3', match.text)
111
+ assert_equal(5, match.length)
112
+ assert_equal(4.5, match.value)
113
+ end
114
+
115
+ def test_division
116
+ match = Calc.parse('20/5')
117
+ assert(match)
118
+ assert_equal(4, match.value)
119
+ end
120
+
121
+ def test_division_float
122
+ match = Calc.parse('4.5/3')
123
+ assert(match)
124
+ assert_equal('4.5/3', match.text)
125
+ assert_equal(5, match.length)
126
+ assert_equal(1.5, match.value)
127
+ end
128
+
129
+ def test_complex
130
+ match = Calc.parse('7*4+3.5*(4.5/3)')
131
+ assert(match)
132
+ assert_equal('7*4+3.5*(4.5/3)', match.text)
133
+ assert_equal(33.25, match.value)
134
+ end
135
+
136
+ def test_complex_spaced
137
+ match = Calc.parse('7 * 4 + 3.5 * (4.5 / 3)')
138
+ assert(match)
139
+ assert_equal(33.25, match.value)
140
+ end
141
+ end
142
+
143
+ end