require 'rubygems' require 'benchmark' require 'rspec' require 'rspec/core/shared_context' require 'polyglot' $LOAD_PATH.unshift File.expand_path('../../lib') require 'treetop' include Treetop module Treetop module ExampleGroupInstanceMethods module ClassMethods attr_accessor :parser_class_under_test def testing_expression(expression_under_test) testing_grammar(%{ grammar Test rule expression_under_test }+expression_under_test+%{ end end }.tabto(0)) end def testing_grammar(grammar_under_test) grammar_node = parse_with_metagrammar(grammar_under_test.strip, :module_or_grammar) parser_code = grammar_node.compile class_eval(parser_code) self.parser_class_under_test = class_eval(grammar_node.parser_name) end def parse_with_metagrammar(input, root) parser = Treetop::Compiler::MetagrammarParser.new parser.root = root node = parser.parse(input) raise parser.failure_reason unless node node end end attr_reader :parser def parse_with_metagrammar(input, root) self.class.parse_with_metagrammar(input, root) end def parser_class_under_test self.class.parser_class_under_test end def parse(input, options = {}) @parser = parser_class_under_test.new unless options[:consume_all_input].nil? parser.consume_all_input = options.delete(:consume_all_input) end result = parser.parse(input, options) yield result if block_given? result end def parse_multibyte(input, options = {}) require 'active_support/all' if RUBY_VERSION !~ /^1.9/ && 'NONE' == $KCODE then $KCODE = 'UTF8' end # rspec 1.3 used to do something similar (set it to 'u') that we need # for activerecord multibyte wrapper to kick in (1.8 only? @todo) parse(input.mb_chars, options) end def compiling_grammar(grammar_under_test) lambda { grammar_node = parse_with_metagrammar(grammar_under_test.strip, :grammar) parser_code = grammar_node.compile [grammar_node, parser_code] } end def compiling_expression(expression_under_test) compiling_grammar(%{ grammar Test rule expression_under_test #{expression_under_test} end end }.tabto(0)) end def optionally_benchmark(&block) if BENCHMARK Benchmark.bm do |x| x.report(&block) end else yield end end end end RSpec.configure do |c| c.mock_with :rr c.extend Treetop::ExampleGroupInstanceMethods::ClassMethods c.include Treetop::ExampleGroupInstanceMethods end class Symbol def to_proc lambda do |x| x.send(self) end end unless method_defined?(:to_proc) end