diff --git a/src/bindings/ruby/Gemfile b/src/bindings/ruby/Gemfile index 9e7a9bec407e905ae865544939da80d4de239b28..df4281435fb46ad55a0f081e9ce583816586f2a5 100644 --- a/src/bindings/ruby/Gemfile +++ b/src/bindings/ruby/Gemfile @@ -3,5 +3,5 @@ source 'https://rubygems.org' gemspec group :test do - # ... + gem 'minitest', '~> 5.2' end diff --git a/src/bindings/ruby/README.md b/src/bindings/ruby/README.md index e69a504aae072f1d6d438c428c1d2ddbc640730e..61ce0b37958abc63e2d603cacfb58d1ea11c0fe4 100644 --- a/src/bindings/ruby/README.md +++ b/src/bindings/ruby/README.md @@ -16,6 +16,8 @@ Ruby bindings for [hammer](https://github.com/UpstandingHackers/hammer), a parsi 3. Run `irb -I ./lib -r hammer` to open `irb` with hammer loaded. +4. To run tests, just run `rake`. + ## Installation diff --git a/src/bindings/ruby/Rakefile b/src/bindings/ruby/Rakefile new file mode 100644 index 0000000000000000000000000000000000000000..70b8662375affb9a9da753d4c2e434ef8748315f --- /dev/null +++ b/src/bindings/ruby/Rakefile @@ -0,0 +1,7 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.pattern = "test/*_test.rb" +end + +task :default => [:test] diff --git a/src/bindings/ruby/lib/hammer.rb b/src/bindings/ruby/lib/hammer.rb index db987b4521a0c930a0c297ca5b39db42058c2b7c..bb0e2a2dafa4b14a31491730ebd1cb60e25b8694 100644 --- a/src/bindings/ruby/lib/hammer.rb +++ b/src/bindings/ruby/lib/hammer.rb @@ -7,79 +7,13 @@ require 'hammer/parser_builder' # people can use "require 'hammer-parser'" in their code. - -# TODO: Put tests in test/ directory. - -parser = Hammer::Parser.build do - token 'blah' - ch 'a'.ord - choice { - sequence { - token 'abc' - } - token 'def' - } -end - -p parser - -if parser - p parser.parse 'blahaabcd' - p parser.parse 'blahadefd' - p parser.parse 'blahablad' - p parser.parse 'blaha' - p parser.parse 'blah' -end - -parser = Hammer::Parser.build { - token 'Hello ' - choice { - token 'Mom' - token 'Dad' - } - token '!' -} -p parser.parse 'Hello Mom!' - -parser = Hammer::ParserBuilder.new - .token('Hello ') - .choice(Hammer::Parser.token('Mom'), Hammer::Parser.token('Dad')) - .token('!') - .build -p parser.parse 'Hello Mom!' - -h = Hammer::Parser -parser = h.sequence(h.token('Hello '), h.choice(h.token('Mom'), h.token('Dad')), h.token('!')) -p parser.parse 'Hello Mom!' - -s = 'blah' -parser = h.token(s) -p parser.parse 'BLAH' # => false -s.upcase! -p parser.parse 'BLAH' # => false - - +# Leave this in for now to be able to play around with HParseResult in irb. x = nil parser = Hammer::Parser.build { token 'abc' x = indirect end_p } -x.bind(h.token('abd')) - -p parser.parse 'abcabdabd' -p parser.parse 'abcabd' -p parser.parse 'abdabd' -p parser.parse 'abd' - -#$r = parser.parse 'abcabd' - - -# Test multibyte characters -parser = Hammer::Parser.build { - token '今日' - end_p -} - -p ($r = parser.parse('今日')) # should succeed +x.bind(Hammer::Parser.token('abd')) +$r = parser.parse 'abcabd' diff --git a/src/bindings/ruby/test/parser_test.rb b/src/bindings/ruby/test/parser_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..d3c4bbb1c0ead85eb94676bb76604d1e71a0336c --- /dev/null +++ b/src/bindings/ruby/test/parser_test.rb @@ -0,0 +1,82 @@ +require 'bundler/setup' +require 'hammer' +require 'minitest/autorun' + +class ParserTest < Minitest::Test + def test_builder_1 + parser = Hammer::Parser.build { + token 'blah' + ch 'a'.ord + choice { + sequence { + token 'abc' + } + token 'def' + } + } + + refute_nil parser + + refute_nil parser.parse('blahaabcd') + refute_nil parser.parse('blahadefd') + assert_nil parser.parse('blahablad') + assert_nil parser.parse('blaha') + assert_nil parser.parse('blah') + end + + def test_builder_2 + parser = Hammer::ParserBuilder.new + .token('Hello ') + .choice(Hammer::Parser.token('Mom'), Hammer::Parser.token('Dad')) + .token('!') + .build + + refute_nil parser + refute_nil parser.parse('Hello Mom!') + end + + def test_builder_3 + h = Hammer::Parser + parser = h.sequence(h.token('Hello '), h.choice(h.token('Mom'), h.token('Dad')), h.token('!')) + + refute_nil parser + refute_nil parser.parse('Hello Mom!') + end + + def test_string_copied + s = 'blah' + parser = Hammer::Parser.token(s) + + refute_equal s, 'BLAH' + assert_nil parser.parse('BLAH') + + # parser still shouldn't match, even if we modify the string in-place + s.upcase! + assert_equal s, 'BLAH' + assert_nil parser.parse('BLAH') + end + + def test_indirect + x = nil + parser = Hammer::Parser.build { + token 'abc' + x = indirect + end_p + } + x.bind(Hammer::Parser.token('abd')) + + assert_nil parser.parse('abcabdabd') + refute_nil parser.parse('abcabd') + assert_nil parser.parse('abdabd') + assert_nil parser.parse('abc') + end + + def test_multibyte_token + parser = Hammer::Parser.build { + token '今日' + end_p + } + + refute_nil parser.parse('今日') + end +end