1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3' 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/core-extensions' 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/grammar' 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/call-stack' 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'test/unit' 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'spec' 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Test 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Location 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :test_path 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def test_group 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.basename( test_path, '.rb' ) 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def test_directory 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.dirname( test_path ) 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def local_path( *parts ) 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.join( test_directory, *parts ) 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def output_directory( name = test_group ) 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver local_path( name ) 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module Location 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule NameSpace 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # import( ruby_file ) => [ new constants, ... ] 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # Read the source code from the path given by +ruby_file+ and 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # evaluate it within the class body. Return new constants 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # created in the class after the evaluation. 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def import( ruby_file ) 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver constants_before = constants 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class_eval( File.read( ruby_file ), ruby_file, 1 ) 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver constants - constants_before 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def import_grammar_targets( grammar ) 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for file in grammar.target_files 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver import( file ) 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule GrammarManager 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Location 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include NameSpace 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DEFAULT_COMPILE_OPTIONS = {} 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add_default_compile_option( name, value ) 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DEFAULT_COMPILE_OPTIONS[ name ] = value 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_function :add_default_compile_option 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ANTLR_JAR = ENV[ 'ANTLR_JAR' ] || ANTLR3.antlr_jar 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver add_default_compile_option( :antlr_jar, ANTLR_JAR ) 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Grammar.global_dependency( ANTLR_JAR ) 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # Compile and load inline grammars on demand when their constant name 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # is referenced in the code. This makes it easier to catch big errors 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # quickly as test cases are run, instead of waiting a few minutes 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # for all grammars to compile, and then discovering there's a big dumb 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # error ruining most of the grammars. 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def const_missing( name ) 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if g = grammars[ name.to_s ] 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver compile( g ) 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammars.delete( name.to_s ) 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const_get( name ) 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif superclass.respond_to?( :grammars ) 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver superclass.const_missing( name ) 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # ^-- for some reason, in ruby 1.9, rspec runs examples as instances of 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # anonymous subclasses, of the actual test class, which messes up the 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # assumptions made in the test code. Grammars are stored in @grammars belonging 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # to the test class, so in 1.9, this method is called with @grammars = {} 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # since it's a subclass 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # An index of grammar file objects created in the test class 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # (defined inline or loaded from a file) 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def grammars 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammars ||= {} 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def grammar_count 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammars.length 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def load_grammar( name ) 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver path = local_path( name.to_s ) 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver path =~ /\.g$/ or path << '.g' 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar = Grammar.new( path, :output_directory => output_directory ) 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver register_grammar( grammar ) 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammar 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def inline_grammar( source, options = {} ) 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver call = call_stack.find { |call| call.file != __FILE__ } 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar = Grammar.inline source, 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :output_directory => output_directory, 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :file => ( call.file rescue nil ), 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :line => ( call.line rescue nil ) 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver register_grammar( grammar ) 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammar 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile_options( defaults = nil ) 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @compile_options ||= DEFAULT_COMPILE_OPTIONS.clone 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @compile_options.update( defaults ) if defaults 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @compile_options 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile( grammar, options = {} ) 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.compile( compile_options.merge( options ) ) 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver import_grammar_targets( grammar ) 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammar 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def register_grammar( grammar ) 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = grammar.name 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammars ||= {} 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if conflict = @grammars[ name ] and conflict.source != grammar.source 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message = "Multiple grammars exist with the name ``#{ name }''" 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise NameError, message 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammars[ name ] = grammar 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module GrammarManager 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Functional < ::Test::Unit::TestCase 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend GrammarManager 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.inherited( klass ) 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver klass.test_path = call_stack[ 0 ].file 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def local_path( *args ) 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.class.local_path( *args ) 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def test_path 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.class.test_path 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def output_directory 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.class.output_directory 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def inline_grammar( source ) 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver call = call_stack.find { |call| call.file != __FILE__ } 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar = Grammar.inline source, 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :output_directory => output_directory, 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :file => call.file, 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :line => call.line 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile_and_load( grammar, options = {} ) 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.class.compile( grammar, options ) 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # class Functional 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule CaptureOutput 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver require 'stringio' 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def output_buffer 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver defined?( @output_buffer ) or @output_buffer = StringIO.new( '' ) 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output_buffer 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def output 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output_buffer.string 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def say( *args ) 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output_buffer.puts( *args ) 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def capture( *args ) 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output_buffer.write( *args ) 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule RaiseErrors 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def emit_error_message( msg ) 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # do nothing 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def report_error( error ) 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise error 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule CollectErrors 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def reported_errors 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver defined?( @reported_errors ) or @reported_errors = [] 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return @reported_errors 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def emit_error_message( msg ) 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver reported_errors << msg 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module Test 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module ANTLR3 232