require 'reap/task' require 'nano/string/margin' # Extract Test Task # # The Reap extract test task scans every package script # looking for =begin testing ... =end sections. # With appropriat headers, it copies these sections # to files in the test dir, which then can be run # using the Reap test taks. # class Reap::TestExt < Reap::Task def task_desc "Extract unit-tests from lib scripts." end attr_accessor :dir, :files, :options def init @dir ||= 'test' @files ||= [ 'lib/**/*.rb' ] #@options end def run #test_libs = @libs.join(':') files = FileList.new files.include(*@files) if files.empty? puts "No script files found." return end print "Reap is scanning and copying embedded tests..." if @dir.strip.empty? puts "Test directory must be specified." return end unless File.directory?(@dir) puts "Test directory doesn't exist: #{File.expand_path( @dir )}" return end files.each { |file| $stdout << '.'; $stdout.flush testing = extract( file ) unless testing.strip.empty? complete_test = create( testing, file ) fp = File.join(@dir,file) unless File.directory?( File.dirname( fp ) ) FileUtils.mkdir_p( File.dirname(fp) ) end File.open( fp, "w" ) { |fw| fw << complete_test } end } puts "done." end def extract( file ) return nil if ! File.file?( file ) tests = ""; inside = false fstr = File.read( file ) fstr.split(/\n/).each do |l| if l =~ /^=[ ]*begin[ ]*testing/ tests << "\n" inside = true next elsif inside and l =~ /^=[ ]*end/ inside = false next end if inside tests << l << "\n" end end tests end def create( testing, file ) fp = file.split(/[\/]/) if fp[0] == 'lib' reqf = "require '#{fp[1..-1].join('/')}'" else reqf = '' end teststr = <<-HERE.margin `# _____ _ `# |_ _|__ ___| |_ `# | |/ _ \\/ __| __| `# | | __/\\__ \\ |_ `# |_|\\___||___/\\__| `# `# for #{file} `# `# Extracted #{Time.now} `# Unit Tools Reap Test Extractor `# ` `#{reqf} ` HERE teststr << testing << "\n" teststr end end