# Title: # Xacto # # Synopsis: # Extractor is a tool for extracting code from embedded comment blocks. # # COPYRIGHT: # Copyright (c) 2006,2007 Thomas Sawyer & Tyler Rick # # LICENSE: # Distributed under the Ruby/GPL dual license. # # Authors: # - Thomas Sawyer # - Tyler Rick # # Todo: # - Should extract_block handle more than the first matching block? # - How can we handle embedded code in stadard comments? Eg. # # - Should this code be wrapped in toplevel Ratchets module? require 'fileutils' require 'facets/string/tabs' # for margin module Xact # module ExtractAndSave extend self # Extract unit tests. This task scans every package script # looking for sections of the form: # # =begin test # ... # =end # # With appropriate headers, it copies these sections to files # in your project's test/ dir, which then can be run using the # Ratchet test task. The exact directory layout of the files to # be tested is reflected in the test directory. You can then # use project.rb's test task to run the tests. # # files Files to extract ['lib/**/*.rb'] # output Test directory ['test/'] # def test_extract(files=nil) output = 'test/embedded' # Don't think output should be setable. files = files || 'lib/**/*.rb' files = 'lib/**/*.rb' if TrueClass == files files = [files].flatten.compact filelist = files.collect{ |f| Dir.glob(f) } filelist.flatten! if filelist.empty? puts "No scripts found from which to extract tests." return end FileUtils.mkdir_p(output) unless File.directory?(output) #vrunner = VerbosityRunner.new("Extracting", verbosity?) #vrunner.setup(filelist.size) filelist.each do |file| #vrunner.prepare(file) testing = extract_test_from_file( file ) if testing.strip.empty? status = "[NONE]" else complete_test = create_test(testing, file) libpath = File.dirname(file) testfile = "test_" + File.basename(file) fp = File.join(output, libpath, testfile) unless File.directory?( File.dirname(fp)) FileUtils.mkdir_p(File.dirname(fp)) end File.open(fp, "w"){ |fw| fw << complete_test } status = "[TEST]" end #vrunner.complete(file, status) end #vrunner.finish( # :normal => "#{filelist.size} files had tests extracted.", # :check => false #) end private # Extract test from a file's testing comments. def extract_test_from_file( file ) return nil if ! File.file?( file ) tests = ""; inside = false fstr = File.read( file ) fstr.split(/\n/).each do |l| if l =~ /^=begin[ ]*test/i tests << "\n" inside = true next elsif inside and l =~ /^=[ ]*end/ inside = false next end if inside tests << l << "\n" end end tests end # Generate the test. def create_test( 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} `# Project.rb Test Extraction `# ` `#{reqf} ` HERE teststr << testing << "\n" teststr end end end