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,26 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class LabelTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = Label.new
7
+ assert_equal(false, rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = Label.new('label', 'a')
12
+
13
+ match = rule.match(input('a'))
14
+ assert(match)
15
+ assert_equal(:label, match.name)
16
+ end
17
+
18
+ def test_to_s
19
+ rule = Label.new('label', 'a')
20
+ assert_equal('label:"a"', rule.to_s)
21
+
22
+ rule = Label.new('label', Sequence.new(%w< a b >))
23
+ assert_equal('label:("a" "b")', rule.to_s)
24
+ end
25
+
26
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class MatchTest < Test::Unit::TestCase
4
+
5
+ Double = Grammar.new {
6
+ include MatchTest::TestGrammar
7
+ root :double
8
+ rule :double do
9
+ one_or_more(:num)
10
+ end
11
+ }
12
+
13
+ Sentence = Grammar.new {
14
+ include MatchTest::TestGrammar
15
+ root :sentence
16
+ rule :word do
17
+ one_or_more(:alpha)
18
+ end
19
+ rule :sentence do
20
+ [ :word, zero_or_more([ ' ', :word ]) ]
21
+ end
22
+ }
23
+
24
+ def test_string
25
+ match = Match.new('hello')
26
+ assert_equal('hello', match.text)
27
+ assert_equal(5, match.length)
28
+ end
29
+
30
+ def test_array_string
31
+ match1 = Match.new('a')
32
+ match2 = Match.new('b')
33
+ match = Match.new([match1, match2])
34
+ assert_equal('ab', match.text)
35
+ assert_equal(2, match.length)
36
+ end
37
+
38
+ def test_match_data
39
+ match = Match.new('hello world'.match(/^(\w+) /))
40
+ assert_equal('hello ', match.text)
41
+ assert_equal(6, match.length)
42
+ end
43
+
44
+ def test_array_match_data
45
+ match1 = Match.new('hello')
46
+ match2 = Match.new(' world'.match(/.+/))
47
+ match = Match.new([match1, match2])
48
+ assert_equal('hello world', match.text)
49
+ assert_equal(11, match.length)
50
+ end
51
+
52
+ def test_matches
53
+ match = Double.parse('123')
54
+ assert(match)
55
+ assert_equal(3, match.matches.length)
56
+ assert_equal(3, match.find(:num).length)
57
+ end
58
+
59
+ def test_match
60
+ match = Double.parse('456')
61
+ assert(match)
62
+ assert_equal(3, match.matches.length)
63
+
64
+ num = match.first(:num)
65
+ assert(num)
66
+ assert_equal('4', num.text)
67
+ assert_equal(4, num.value)
68
+ end
69
+
70
+ def test_matches_deep
71
+ match = Sentence.parse('one two three four')
72
+ assert(match)
73
+ assert_equal(15, match.find(:alpha).length)
74
+ end
75
+
76
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class NotPredicateTest < Test::Unit::TestCase
4
+
5
+ def test_terminal?
6
+ rule = NotPredicate.new
7
+ assert_equal(false, rule.terminal?)
8
+ end
9
+
10
+ def test_match
11
+ rule = NotPredicate.new('a')
12
+
13
+ match = rule.match(input('a'))
14
+ assert_equal(nil, match)
15
+
16
+ match = rule.match(input('b'))
17
+ assert(match)
18
+ assert_equal('', match.text)
19
+ assert_equal(0, match.length)
20
+ end
21
+
22
+ def test_to_s
23
+ rule = NotPredicate.new('a')
24
+ assert_equal('!"a"', rule.to_s)
25
+ end
26
+
27
+ end
@@ -0,0 +1,663 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require 'citrus/peg'
3
+
4
+ class PEGTest < Test::Unit::TestCase
5
+
6
+ # A shortcut for creating a grammar that includes Citrus::PEG but uses a
7
+ # different root.
8
+ def peg(root_rule)
9
+ Grammar.new {
10
+ include Citrus::PEG
11
+ root root_rule
12
+ }
13
+ end
14
+
15
+
16
+ ## File tests
17
+
18
+
19
+ def run_file_test(file, root)
20
+ grammar = peg(root)
21
+ code = File.read(file)
22
+ match = grammar.parse(code)
23
+ assert(match)
24
+ end
25
+
26
+ %w< rule grammar >.each do |type|
27
+ Dir[File.dirname(__FILE__) + "/_files/#{type}*.citrus"].each do |path|
28
+ module_eval(<<-RUBY.gsub(/^ /, ''), __FILE__, __LINE__ + 1)
29
+ def test_#{File.basename(path, '.citrus')}
30
+ run_file_test("#{path}", :#{type})
31
+ end
32
+ RUBY
33
+ end
34
+ end
35
+
36
+
37
+ ## Hierarchical syntax
38
+
39
+
40
+ def test_rule_body
41
+ grammar = peg(:rule_body)
42
+
43
+ match = grammar.parse('"a" | "b"')
44
+ assert(match)
45
+ assert_kind_of(Rule, match.value)
46
+ assert_instance_of(Choice, match.value)
47
+
48
+ match = grammar.parse('rule_name')
49
+ assert(match)
50
+ assert_kind_of(Rule, match.value)
51
+ assert_instance_of(Alias, match.value)
52
+
53
+ match = grammar.parse('""')
54
+ assert(match)
55
+ assert_kind_of(Rule, match.value)
56
+ assert_instance_of(FixedWidth, match.value)
57
+
58
+ match = grammar.parse('"a"')
59
+ assert(match)
60
+ assert_kind_of(Rule, match.value)
61
+ assert_instance_of(FixedWidth, match.value)
62
+
63
+ match = grammar.parse('"a" "b"')
64
+ assert(match)
65
+ assert_kind_of(Rule, match.value)
66
+ assert_instance_of(Sequence, match.value)
67
+
68
+ match = grammar.parse('"a" | "b"')
69
+ assert(match)
70
+ assert_kind_of(Rule, match.value)
71
+ assert_instance_of(Choice, match.value)
72
+
73
+ match = grammar.parse('.')
74
+ assert(match)
75
+ assert_kind_of(Rule, match.value)
76
+ assert_instance_of(Expression, match.value)
77
+
78
+ match = grammar.parse('[a-z]')
79
+ assert(match)
80
+ assert_kind_of(Rule, match.value)
81
+ assert_instance_of(Expression, match.value)
82
+
83
+ match = grammar.parse('/./')
84
+ assert(match)
85
+ assert_kind_of(Rule, match.value)
86
+ assert_instance_of(Expression, match.value)
87
+
88
+ match = grammar.parse('/./ /./')
89
+ assert(match)
90
+ assert_kind_of(Rule, match.value)
91
+ assert_instance_of(Sequence, match.value)
92
+ assert_equal(2, match.find(:regular_expression).length)
93
+
94
+ match = grammar.parse('/./ | /./')
95
+ assert(match)
96
+ assert_kind_of(Rule, match.value)
97
+ assert_instance_of(Choice, match.value)
98
+ assert_equal(1, match.find(:bar).length)
99
+ assert_equal(2, match.find(:regular_expression).length)
100
+ assert_equal(0, match.find(:anything_symbol).length)
101
+
102
+ match = grammar.parse('"" {}')
103
+ assert(match)
104
+ assert_kind_of(Rule, match.value)
105
+ assert_instance_of(FixedWidth, match.value)
106
+
107
+ match = grammar.parse('""* {}')
108
+ assert(match)
109
+ assert_kind_of(Rule, match.value)
110
+ assert_instance_of(Repeat, match.value)
111
+
112
+ match = grammar.parse('("a" "b")*')
113
+ assert(match)
114
+ assert_kind_of(Rule, match.value)
115
+ assert_instance_of(Repeat, match.value)
116
+
117
+ match = grammar.parse('"a" | "b"')
118
+ assert(match)
119
+ assert_kind_of(Rule, match.value)
120
+ assert_instance_of(Choice, match.value)
121
+
122
+ match = grammar.parse('("a" | "b")*')
123
+ assert(match)
124
+ assert_kind_of(Rule, match.value)
125
+ assert_instance_of(Repeat, match.value)
126
+
127
+ match = grammar.parse('("a" "b")* {}')
128
+ assert(match)
129
+ assert_kind_of(Rule, match.value)
130
+ assert_instance_of(Repeat, match.value)
131
+
132
+ match = grammar.parse('("a" | "b")* {}')
133
+ assert(match)
134
+ assert_kind_of(Rule, match.value)
135
+ assert_instance_of(Repeat, match.value)
136
+
137
+ match = grammar.parse('("a" | /./)')
138
+ assert(match)
139
+ assert_kind_of(Rule, match.value)
140
+ assert_instance_of(Choice, match.value)
141
+
142
+ # Test precedence of Sequence over Choice.
143
+ match = grammar.parse('"a" "b" | "c"')
144
+ assert(match)
145
+ assert_kind_of(Rule, match.value)
146
+ assert_instance_of(Choice, match.value)
147
+
148
+ match = grammar.parse('"a" ("b" | /./)* {}')
149
+ assert(match)
150
+ assert_kind_of(Rule, match.value)
151
+ assert_instance_of(Sequence, match.value)
152
+
153
+ match = grammar.parse('("a" "b")* <Module>')
154
+ assert(match)
155
+ assert_kind_of(Rule, match.value)
156
+ assert_instance_of(Repeat, match.value)
157
+
158
+ match = grammar.parse('( "a" "b" )* <Module>')
159
+ assert(match)
160
+ assert_kind_of(Rule, match.value)
161
+ assert_instance_of(Repeat, match.value)
162
+
163
+ match = grammar.parse('( "a" "b" ) <Module>')
164
+ assert(match)
165
+ assert_kind_of(Rule, match.value)
166
+ assert_instance_of(Sequence, match.value)
167
+
168
+ match = grammar.parse('("a" | "b")* <Module>')
169
+ assert(match)
170
+ assert_kind_of(Rule, match.value)
171
+ assert_instance_of(Repeat, match.value)
172
+
173
+ match = grammar.parse('("a" | "b") <Module>')
174
+ assert(match)
175
+ assert_kind_of(Rule, match.value)
176
+ assert_instance_of(Choice, match.value)
177
+
178
+ match = grammar.parse('"a" ("b" | /./)* <Module>')
179
+ assert(match)
180
+ assert_kind_of(Rule, match.value)
181
+ assert_instance_of(Sequence, match.value)
182
+
183
+ match = grammar.parse("[0-9] {\n def value\n text.to_i\n end\n}\n")
184
+ assert(match)
185
+ assert_kind_of(Rule, match.value)
186
+ assert_instance_of(Expression, match.value)
187
+
188
+ match = grammar.parse("[0-9]+ {\n def value\n text.to_i\n end\n}\n")
189
+ assert(match)
190
+ assert_kind_of(Rule, match.value)
191
+ assert_instance_of(Repeat, match.value)
192
+ end
193
+
194
+ def test_sequence
195
+ grammar = peg(:sequence)
196
+
197
+ match = grammar.parse('"" ""')
198
+ assert(match)
199
+ assert_kind_of(Rule, match.value)
200
+ assert_instance_of(Sequence, match.value)
201
+
202
+ match = grammar.parse('"a" "b" "c"')
203
+ assert(match)
204
+ assert_kind_of(Rule, match.value)
205
+ assert_instance_of(Sequence, match.value)
206
+ end
207
+
208
+ def test_prefix
209
+ grammar = peg(:prefix)
210
+
211
+ match = grammar.parse('&""')
212
+ assert(match)
213
+ assert_kind_of(Rule, match.value)
214
+ assert_instance_of(AndPredicate, match.value)
215
+
216
+ match = grammar.parse('!""')
217
+ assert(match)
218
+ assert_kind_of(Rule, match.value)
219
+ assert_instance_of(NotPredicate, match.value)
220
+
221
+ match = grammar.parse('label:""')
222
+ assert(match)
223
+ assert_kind_of(Rule, match.value)
224
+ assert_instance_of(Label, match.value)
225
+
226
+ match = grammar.parse('label :"" ')
227
+ assert(match)
228
+ assert_kind_of(Rule, match.value)
229
+ assert_instance_of(Label, match.value)
230
+ end
231
+
232
+ def test_appendix
233
+ grammar = peg(:appendix)
234
+
235
+ match = grammar.parse('"" <Module>')
236
+ assert(match)
237
+ assert_kind_of(Rule, match.value)
238
+ assert_kind_of(Module, match.value.ext)
239
+
240
+ match = grammar.parse('"" {}')
241
+ assert(match)
242
+ assert_kind_of(Rule, match.value)
243
+ assert_kind_of(Module, match.value.ext)
244
+
245
+ match = grammar.parse('"" {} ')
246
+ assert(match)
247
+ assert_kind_of(Rule, match.value)
248
+ assert_kind_of(Module, match.value.ext)
249
+ end
250
+
251
+ def test_suffix
252
+ grammar = peg(:suffix)
253
+
254
+ match = grammar.parse('""+')
255
+ assert(match)
256
+ assert_kind_of(Rule, match.value)
257
+ assert_instance_of(Repeat, match.value)
258
+
259
+ match = grammar.parse('""? ')
260
+ assert(match)
261
+ assert_kind_of(Rule, match.value)
262
+ assert_instance_of(Repeat, match.value)
263
+
264
+ match = grammar.parse('""1* ')
265
+ assert(match)
266
+ assert_kind_of(Rule, match.value)
267
+ assert_instance_of(Repeat, match.value)
268
+ end
269
+
270
+ def test_primary
271
+ grammar = peg(:primary)
272
+
273
+ match = grammar.parse('rule_name')
274
+ assert(match)
275
+ assert_kind_of(Rule, match.value)
276
+ assert_instance_of(Alias, match.value)
277
+
278
+ match = grammar.parse('"a"')
279
+ assert(match)
280
+ assert_kind_of(Rule, match.value)
281
+ assert_instance_of(FixedWidth, match.value)
282
+ end
283
+
284
+
285
+ ## Lexical syntax
286
+
287
+
288
+ def test_require
289
+ grammar = peg(:require)
290
+
291
+ match = grammar.parse('require "some/file"')
292
+ assert(match)
293
+ assert_equal('some/file', match.value)
294
+
295
+ match = grammar.parse('require"some/file"')
296
+ assert(match)
297
+ assert_equal('some/file', match.value)
298
+
299
+ match = grammar.parse("require 'some/file'")
300
+ assert(match)
301
+ assert_equal('some/file', match.value)
302
+ end
303
+
304
+ def test_include
305
+ grammar = peg(:include)
306
+
307
+ match = grammar.parse('include Module')
308
+ assert(match)
309
+ assert_equal('Module', match.value)
310
+
311
+ match = grammar.parse('include ::Module')
312
+ assert(match)
313
+ assert_equal('::Module', match.value)
314
+ end
315
+
316
+ def test_root
317
+ grammar = peg(:root)
318
+
319
+ match = grammar.parse('root some_rule')
320
+ assert(match)
321
+ assert_equal('some_rule', match.value)
322
+
323
+ assert_raise ParseError do
324
+ match = grammar.parse('root :a_root')
325
+ end
326
+ end
327
+
328
+ def test_rule_name
329
+ grammar = peg(:rule_name)
330
+
331
+ match = grammar.parse('some_rule')
332
+ assert(match)
333
+ assert('some_rule', match.value)
334
+
335
+ match = grammar.parse('some_rule ')
336
+ assert(match)
337
+ assert('some_rule', match.value)
338
+ end
339
+
340
+ def test_terminal
341
+ grammar = peg(:terminal)
342
+
343
+ match = grammar.parse('"a"')
344
+ assert(match)
345
+ assert_kind_of(Rule, match.value)
346
+ assert_instance_of(FixedWidth, match.value)
347
+ assert(match.value.terminal?)
348
+
349
+ match = grammar.parse('[a-z]')
350
+ assert(match)
351
+ assert_kind_of(Rule, match.value)
352
+ assert_instance_of(Expression, match.value)
353
+ assert(match.value.terminal?)
354
+
355
+ match = grammar.parse('.')
356
+ assert(match)
357
+ assert_kind_of(Rule, match.value)
358
+ assert_instance_of(Expression, match.value)
359
+ assert(match.value.terminal?)
360
+
361
+ match = grammar.parse('/./')
362
+ assert(match)
363
+ assert_kind_of(Rule, match.value)
364
+ assert_instance_of(Expression, match.value)
365
+ assert(match.value.terminal?)
366
+ end
367
+
368
+ def test_single_quoted_string
369
+ grammar = peg(:quoted_string)
370
+
371
+ match = grammar.parse("'test'")
372
+ assert(match)
373
+ assert_equal('test', match.value)
374
+
375
+ match = grammar.parse("'te\\'st'")
376
+ assert(match)
377
+ assert_equal("te'st", match.value)
378
+
379
+ match = grammar.parse("'te\"st'")
380
+ assert(match)
381
+ assert_equal('te"st', match.value)
382
+ end
383
+
384
+ def test_double_quoted_string
385
+ grammar = peg(:quoted_string)
386
+
387
+ match = grammar.parse('"test"')
388
+ assert(match)
389
+ assert_equal('test', match.value)
390
+
391
+ match = grammar.parse('"te\\"st"')
392
+ assert(match)
393
+ assert_equal('te"st', match.value)
394
+
395
+ match = grammar.parse('"te\'st"')
396
+ assert(match)
397
+ assert_equal("te'st", match.value)
398
+
399
+ match = grammar.parse('"\\x26"')
400
+ assert(match)
401
+ assert_equal('&', match.value)
402
+ end
403
+
404
+ def test_character_class
405
+ grammar = peg(:character_class)
406
+
407
+ match = grammar.parse('[_]')
408
+ assert(match)
409
+ assert_equal(/[_]/, match.value)
410
+
411
+ match = grammar.parse('[a-z]')
412
+ assert(match)
413
+ assert_equal(/[a-z]/, match.value)
414
+
415
+ match = grammar.parse('[a-z0-9]')
416
+ assert(match)
417
+ assert_equal(/[a-z0-9]/, match.value)
418
+
419
+ match = grammar.parse('[\\x26-\\x29]')
420
+ assert(match)
421
+ assert_equal(/[\x26-\x29]/, match.value)
422
+ end
423
+
424
+ def test_anything_symbol
425
+ grammar = peg(:anything_symbol)
426
+
427
+ match = grammar.parse('.')
428
+ assert(match)
429
+ assert_equal(/./m, match.value)
430
+ end
431
+
432
+ def test_regular_expression
433
+ grammar = peg(:regular_expression)
434
+
435
+ match = grammar.parse('/./')
436
+ assert(match)
437
+ assert_equal(/./, match.value)
438
+
439
+ match = grammar.parse('/\\//')
440
+ assert(match)
441
+ assert_equal(/\//, match.value)
442
+
443
+ match = grammar.parse('/\\\\/')
444
+ assert(match)
445
+ assert_equal(/\\/, match.value)
446
+
447
+ match = grammar.parse('/\\x26/')
448
+ assert(match)
449
+ assert_equal(/\x26/, match.value)
450
+
451
+ match = grammar.parse('/a/i')
452
+ assert(match)
453
+ assert_equal(/a/i, match.value)
454
+ end
455
+
456
+ def test_qualifier
457
+ grammar = peg(:qualifier)
458
+
459
+ match = grammar.parse('&')
460
+ assert(match)
461
+ assert_kind_of(Rule, match.wrap(''))
462
+
463
+ match = grammar.parse('!')
464
+ assert(match)
465
+ assert_kind_of(Rule, match.wrap(''))
466
+ end
467
+
468
+ def test_and
469
+ grammar = peg(:and)
470
+
471
+ match = grammar.parse('&')
472
+ assert(match)
473
+ assert_instance_of(AndPredicate, match.wrap(''))
474
+
475
+ match = grammar.parse('& ')
476
+ assert(match)
477
+ assert_instance_of(AndPredicate, match.wrap(''))
478
+ end
479
+
480
+ def test_not
481
+ grammar = peg(:not)
482
+
483
+ match = grammar.parse('!')
484
+ assert(match)
485
+ assert_instance_of(NotPredicate, match.wrap(''))
486
+
487
+ match = grammar.parse('! ')
488
+ assert(match)
489
+ assert_instance_of(NotPredicate, match.wrap(''))
490
+ end
491
+
492
+ def test_label
493
+ grammar = peg(:label)
494
+
495
+ match = grammar.parse('label:')
496
+ assert(match)
497
+ assert_equal('label', match.value)
498
+ assert_instance_of(Label, match.wrap(''))
499
+
500
+ match = grammar.parse('a_label : ')
501
+ assert(match)
502
+ assert_equal('a_label', match.value)
503
+ assert_instance_of(Label, match.wrap(''))
504
+ end
505
+
506
+ def test_tag
507
+ grammar = peg(:tag)
508
+
509
+ match = grammar.parse('<Module>')
510
+ assert(match)
511
+ assert_equal(Module, match.value)
512
+
513
+ match = grammar.parse('< Module >')
514
+ assert(match)
515
+ assert_equal(Module, match.value)
516
+
517
+ match = grammar.parse('<Module> ')
518
+ assert(match)
519
+ assert_equal(Module, match.value)
520
+ end
521
+
522
+ def test_block
523
+ grammar = peg(:block)
524
+
525
+ match = grammar.parse('{}')
526
+ assert(match)
527
+ assert(match.value)
528
+
529
+ match = grammar.parse("{} \n")
530
+ assert(match)
531
+ assert(match.value)
532
+
533
+ match = grammar.parse('{ 2 }')
534
+ assert(match)
535
+ assert(match.value)
536
+ assert_equal(2, match.value.call)
537
+
538
+ match = grammar.parse("{ {:a => :b}\n}")
539
+ assert(match)
540
+ assert(match.value)
541
+ assert_equal({:a => :b}, match.value.call)
542
+
543
+ match = grammar.parse("{|b|\n Proc.new(&b)\n}")
544
+ assert(match)
545
+ assert(match.value)
546
+
547
+ b = match.value.call(Proc.new { :hi })
548
+
549
+ assert(b)
550
+ assert_equal(:hi, b.call)
551
+
552
+ match = grammar.parse("{\n def value\n 'a'\n end\n} ")
553
+ assert(match)
554
+ assert(match.value)
555
+ end
556
+
557
+ def test_quantifier
558
+ grammar = peg(:quantifier)
559
+
560
+ match = grammar.parse('?')
561
+ assert(match)
562
+ assert_instance_of(Repeat, match.wrap(''))
563
+
564
+ match = grammar.parse('+')
565
+ assert(match)
566
+ assert_instance_of(Repeat, match.wrap(''))
567
+
568
+ match = grammar.parse('*')
569
+ assert(match)
570
+ assert_instance_of(Repeat, match.wrap(''))
571
+ end
572
+
573
+ def test_question
574
+ grammar = peg(:question)
575
+
576
+ match = grammar.parse('?')
577
+ assert(match)
578
+ assert_equal(0, match.min)
579
+ assert_equal(1, match.max)
580
+
581
+ match = grammar.parse('? ')
582
+ assert(match)
583
+ assert_equal(0, match.min)
584
+ assert_equal(1, match.max)
585
+ end
586
+
587
+ def test_plus
588
+ grammar = peg(:plus)
589
+
590
+ match = grammar.parse('+')
591
+ assert(match)
592
+ assert_equal(1, match.min)
593
+ assert_equal(Infinity, match.max)
594
+
595
+ match = grammar.parse('+ ')
596
+ assert(match)
597
+ assert_equal(1, match.min)
598
+ assert_equal(Infinity, match.max)
599
+ end
600
+
601
+ def test_repeat
602
+ grammar = peg(:repeat)
603
+
604
+ match = grammar.parse('*')
605
+ assert(match)
606
+ assert_equal(0, match.min)
607
+ assert_equal(Infinity, match.max)
608
+
609
+ match = grammar.parse('1*')
610
+ assert(match)
611
+ assert_equal(1, match.min)
612
+ assert_equal(Infinity, match.max)
613
+
614
+ match = grammar.parse('*2')
615
+ assert(match)
616
+ assert_equal(0, match.min)
617
+ assert_equal(2, match.max)
618
+
619
+ match = grammar.parse('1*2')
620
+ assert(match)
621
+ assert_equal(1, match.min)
622
+ assert_equal(2, match.max)
623
+
624
+ match = grammar.parse('1*2 ')
625
+ assert(match)
626
+ assert_equal(1, match.min)
627
+ assert_equal(2, match.max)
628
+ end
629
+
630
+ def test_module_name
631
+ grammar = peg(:module_name)
632
+
633
+ match = grammar.parse('Module')
634
+ assert(match)
635
+
636
+ match = grammar.parse('::Proc')
637
+ assert(match)
638
+ end
639
+
640
+ def test_constant
641
+ grammar = peg(:constant)
642
+
643
+ match = grammar.parse('Math')
644
+ assert(match)
645
+
646
+ assert_raise ParseError do
647
+ match = grammar.parse('math')
648
+ end
649
+ end
650
+
651
+ def test_comment
652
+ grammar = peg(:comment)
653
+
654
+ match = grammar.parse('# A comment.')
655
+ assert(match)
656
+ assert_equal('# A comment.', match.text)
657
+
658
+ assert_raise ParseError do
659
+ match = grammar.parse("# A comment.\n")
660
+ end
661
+ end
662
+
663
+ end