diff --git a/test/mains/helper.rb b/test/mains/helper.rb index bb161258..23136d36 100644 --- a/test/mains/helper.rb +++ b/test/mains/helper.rb @@ -1,4 +1,79 @@ require_relative '../helper' module Mains + module MainsHelper + include Preloader + include ScopeHelper + + def setup + @qemu = ENV["qemu-arm"] || "qemu-arm" + @linker = ENV["arm-linux-gnu-ld"] || "arm-linux-gnu-ld" #on fedora + @arm = ENV["TEST_ARM"] or ENV["TEST_ALL"] + #@linker = "arm-linux-gnueabi-ld" # on ubuntu + # ENV["TEST_ARM"] = "DEBUG" + end + + def assert_result( exit_code , stdout , name = nil) + name = caller_locations.first.label unless name + input = preload + @input + code , out = run_interpreter( input , name) + assert_equal exit_code , code , "interpreter code for #{name}" + assert_equal stdout , out , "interpreter stdout for #{name}" + return unless @arm + code , out = run_arm( input , name) + assert_equal exit_code , code , "arm code for #{name}" + assert_equal stdout , out , "arm stdout for #{name}" + end + + # runnable_methods is called by minitest to determine which tests to run + def self.runnable_methods + all = Dir["test/mains/source/*_*.rb"] + tests =[] + return tests unless has_qemu + all.each do |file_name| + fullname = file_name.split("/").last.split(".").first + order , name , stdout , exit_code = fullname.split("_") + method_name = "test_#{order}_#{name}" + input = File.read(file_name) + tests << method_name + self.send(:define_method, method_name ) do + out , code = run_code(input , "#{order}_#{name}") + assert_equal stdout , out , "Wrong stdout #{name}" + assert_equal exit_code , code.to_s , "Wrong exit code #{name}" + end + end + tests + end + + def run_arm(input , name ) + puts "Compiling #{name}" if ENV["TEST_ARM"] == "DEBUG" + linker = ::RubyX::RubyXCompiler.new({}).ruby_to_binary( input , :arm ) + writer = Elf::ObjectWriter.new(linker) + writer.save "mains.o" + puts "Linking #{name}" if ENV["TEST_ARM"] == "DEBUG" + `#{@linker} -N mains.o` + assert_equal 0 , $?.exitstatus , "Linking #{name} failed #{$?}" + puts "Running #{name}" if ENV["TEST_ARM"] == "DEBUG" + stdout = `#{@qemu} ./a.out` + exit_code = $?.exitstatus + puts "Arm #{stdout} #{exit_code}" if ENV["TEST_ARM"] == "DEBUG" + return exit_code , stdout + end + + def run_interpreter(input , name ) + puts "Interpreting #{name}" if ENV["TEST_ARM"] == "DEBUG" + compiler = RubyX::RubyXCompiler.new(RubyX.default_test_options) + linker = compiler.ruby_to_binary(input , :interpreter) + interpreter = Risc::Interpreter.new(linker) + interpreter.start_program + interpreter.tick while(interpreter.instruction) + saved_in = interpreter.std_reg(:saved_message) + assert_equal Parfait::Message , interpreter.get_register(saved_in).class + ret = interpreter.get_register(interpreter.std_reg(:syscall_1)) + puts "Interpret #{interpreter.stdout} #{ret}" if ENV["TEST_ARM"] == "DEBUG" + return ret , interpreter.stdout + end + + end + end diff --git a/test/mains/test_assign.rb b/test/mains/test_assign.rb new file mode 100644 index 00000000..32408742 --- /dev/null +++ b/test/mains/test_assign.rb @@ -0,0 +1,31 @@ +require_relative "helper" + +module Mains + class AssignTester < MiniTest::Test + include MainsHelper + + def test_local + @input = as_main 'a = 15 ; return a' + assert_result 15 , "" + end + + def test_plus + @preload = "Integer.plus" + @input = as_main("a = 5 + 5 ; return a") + assert_result 10 , "" + end + + def test_plus2 + @preload = "Integer.plus" + @input = as_main("a = 5 ;a = 5 + a ; return a") + assert_result 10 , "" + end + + def test_plus3 + @preload = "Integer.plus" + @input = as_main("a = 5 ;a = 5 + a ;a = a + 5; return a") + assert_result 15 , "" + end + + end +end