require File.expand_path('../helper', __FILE__) class GrammarTest < Test::Unit::TestCase def test_new grammar = Grammar.new assert_kind_of(Module, grammar) assert(grammar.include?(Grammar)) end def test_name assert_equal("Test::Unit::TestCase::TestGrammar", TestGrammar.name) end def test_no_name grammar = Grammar.new assert_equal('', grammar.name) end def test_rule_names assert_equal([:alpha, :num, :alphanum], TestGrammar.rule_names) end def test_has_name assert(TestGrammar.has_rule?('alpha')) assert(TestGrammar.has_rule?(:alpha)) end def test_doesnt_have_name assert_equal(false, TestGrammar.has_rule?(:value)) end def test_parse_fixed_width grammar = Grammar.new { rule(:abc) { 'abc' } } match = grammar.parse('abc') assert(match) assert_equal('abc', match) assert_equal(3, match.length) end def test_parse_expression grammar = Grammar.new { rule(:alpha) { /[a-z]+/i } } match = grammar.parse('abc') assert(match) assert_equal('abc', match) assert_equal(3, match.length) end def test_parse_sequence grammar = Grammar.new { rule(:num) { all(1, 2, 3) } } match = grammar.parse('123') assert(match) assert_equal('123', match) assert_equal(3, match.length) end def test_parse_sequence_long grammar = Grammar.new { rule(:num) { all(1, 2, 3) } } match = grammar.parse('1234', :consume => false) assert(match) assert_equal('123', match) assert_equal(3, match.length) end def test_parse_sequence_short grammar = Grammar.new { rule(:num) { all(1, 2, 3) } } assert_raise ParseError do grammar.parse('12') end end def test_parse_choice grammar = Grammar.new { rule(:alphanum) { any(/[a-z]/i, 0..9) } } match = grammar.parse('a') assert(match) assert_equal('a', match) assert_equal(1, match.length) match = grammar.parse('1') assert(match) assert_equal('1', match) assert_equal(1, match.length) end def test_parse_choice_miss grammar = Grammar.new { rule(:alphanum) { any(/[a-z]/, 0..9) } } assert_raise ParseError do grammar.parse('A') end end def test_parse_recurs grammar = Grammar.new { rule(:paren) { any(['(', :paren, ')'], /[a-z]/) } } match = grammar.parse('a') assert(match) assert_equal('a', match) assert_equal(1, match.length) match = grammar.parse('((a))') assert(match) assert_equal('((a))', match) assert_equal(5, match.length) n = 100 str = ('(' * n) + 'a' + (')' * n) match = grammar.parse(str) assert(match) assert_equal(str, match) assert_equal(str.length, match.length) end def test_parse_file grammar = Grammar.new { rule("words"){ rep(any(" ", /[a-z]+/)) } } require 'tempfile' Tempfile.open('citrus') do |tmp| tmp << "abd def" tmp.close match = grammar.parse_file(tmp.path) assert(match) assert_instance_of(Input, match.input) assert_instance_of(Pathname, match.source) match.matches.each do |m| assert_instance_of(Input, m.input) assert_instance_of(Pathname, m.source) end end end def test_labeled_production grammar = Grammar.new { rule(:abc) { label('abc', :p){ capture(:p) } } } assert_equal('abc', grammar.parse('abc').value) end def test_global_grammar assert_raise ArgumentError do grammar(:abc) end end end