# Some common routines used in testing. require 'fileutils' # require 'diff/lcs' # require 'diff/lcs/hunk' # begin require 'rubygems' rescue LoadError end # require 'ruby-debug'; Debugger.start module TestHelper # FIXME: turn args into a hash. def run_debugger(testname, args='', outfile=nil, filter=nil, old_code=false, debug_pgm='tdebug.rb') rightfile = File.join('data', "#{testname}.right") outfile = "#{testname}.out" unless outfile if File.exists?(outfile) FileUtils.rm(outfile) end ENV['RDEBUG'] = debug_pgm if old_code cmd = "/bin/sh #{File.join('..', 'runner.sh')} #{args} >#{outfile}" else cmd = "../rdbg.rb #{args} >#{outfile}" end # puts cmd output = `#{cmd}` got_lines = File.read(outfile).split(/\n/) correct_lines = File.read(rightfile).split(/\n/) filter.call(got_lines, correct_lines) if filter if cheap_diff(got_lines, correct_lines) FileUtils.rm(outfile) return true end return false end def cheap_diff(got_lines, correct_lines) puts got_lines if $DEBUG correct_lines.each_with_index do |line, i| correct_lines[i].chomp! if got_lines[i] != correct_lines[i] puts "difference found at line #{i+1}" puts "got : #{got_lines[i]}" puts "need: #{correct_lines[i]}" return false end end if correct_lines.size != got_lines.size puts("difference in number of lines: " + "#{correct_lines.size} vs. #{got_lines.size}") return false end return true end # FIXME: using this causes the same test to get run several times # and some tests fail probably because of a lack of environment isolation. # Many tests follow a basic pattern: run the debugger with a given # debugger script and compare output produced. The following creates # this kind of test. def add_test(base_name, src_dir, script_name=nil, cmd=nil, test_name=nil) puts "+++ Adding #{base_name} ++++" if $DEBUG test_name = base_name unless test_name script_name = File.join('data', test_name + '.cmd') unless script_name cmd = 'gcd.rb 3 5' unless cmd eval <<-EOF def test_#{test_name} Dir.chdir(\"#{src_dir}\") do assert_equal(true, run_debugger(\"#{base_name}\", \"--script #{script_name} -- #{cmd}\")) end end EOF end module_function :add_test # Adapted from the Ruby Cookbook, Section 6.10: Comparing two files. # def diff_as_string(rightfile, checkfile, format=:unified, context_lines=3) # right_data = File.read(rightfile) # check_data = File.read(checkfile) # output = '' # diffs = Diff::LCS.diff(right_data, check_data) # return output if diffs.empty? # oldhunk = hunk = nil # file_length_difference = 0 # diffs.each do |piece| # begin # hunk = Diff::LCS::Hunk.new(right_data, check_data, piece, # context_lines, file_length_difference) # next unless oldhunk # # # Hunks may overlap, which is why we need to be careful when our # # diff includes lines of context. Otherwise, we might print # # redundant lines. # if (context_lines > 0) and hunk.overlaps?(oldhunk) # hunk.unshift(oldhunk) # else # output << oldhunk.diff(format) # end # ensure # oldhunk = hunk # output << '\n' # end # end # # Handle the last remaining hunk # output << oldhunk.diff(format) << '\n' # end end