Working on running specs in separate processes
This commit is contained in:
parent
3d467f3c11
commit
5249826cb7
|
@ -9,3 +9,4 @@ log
|
|||
.project
|
||||
.loadpath
|
||||
*.swp
|
||||
results
|
||||
|
|
6
Rakefile
6
Rakefile
|
@ -86,4 +86,10 @@ Rake::RDocTask.new(:docs) do |rd|
|
|||
rd.rdoc_files = files.uniq
|
||||
title = "webrat-#{Webrat::VERSION} Documentation"
|
||||
rd.options << "-t #{title}"
|
||||
end
|
||||
|
||||
desc "Run all specs"
|
||||
task "spec2" do
|
||||
require "lib/webrat/test/run_specs"
|
||||
run_specs(Dir["#{Dir.pwd}/spec//**/*_spec.rb"])
|
||||
end
|
|
@ -0,0 +1,40 @@
|
|||
require "stringio"
|
||||
require 'rubygems'
|
||||
require 'spec'
|
||||
require 'spec/runner/formatter/specdoc_formatter'
|
||||
|
||||
module Spec
|
||||
module Runner
|
||||
module Formatter
|
||||
class BaseTextFormatter
|
||||
def dump_failure(counter, failure)
|
||||
output = @options.error_stream
|
||||
output.puts
|
||||
output.puts "#{counter.to_s})"
|
||||
output.puts colourise("#{failure.header}\n#{failure.exception.message}", failure)
|
||||
output.puts format_backtrace(failure.exception.backtrace)
|
||||
output.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_spec(spec, base_dir)
|
||||
|
||||
$VERBOSE = nil
|
||||
err, out = StringIO.new, StringIO.new
|
||||
def out.tty?() true end
|
||||
options = Spec::Runner::OptionParser.parse(%W(#{spec} -fs --color), err, out)
|
||||
options.filename_pattern = File.expand_path(spec)
|
||||
failure = ! Spec::Runner::CommandLine.run(options)
|
||||
File.open(File.join(base_dir, "results", "#{File.basename(spec)}_out"), "w") do |file|
|
||||
file.puts out.string
|
||||
end
|
||||
File.open(File.join(base_dir, "results", "#{File.basename(spec)}_err"), "w") do |file|
|
||||
file.puts err.string
|
||||
end
|
||||
exit!(failure ? -1 : 0)
|
||||
end
|
||||
|
||||
run_spec(ARGV[0], File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))) if ENV["NOW"]
|
|
@ -0,0 +1,133 @@
|
|||
require 'rubygems'
|
||||
require 'benchmark'
|
||||
require 'spec'
|
||||
require 'spec/runner/formatter/base_text_formatter'
|
||||
require 'spec/spec_helper.rb'
|
||||
|
||||
# Load this stuff so it only has to be loaded once for the entire suite
|
||||
require 'spec/mocks'
|
||||
require 'spec/mocks/extensions'
|
||||
require 'spec/runner/formatter/specdoc_formatter'
|
||||
require 'base64'
|
||||
require 'nkf'
|
||||
require 'kconv'
|
||||
require 'rack'
|
||||
require 'fileutils'
|
||||
|
||||
begin
|
||||
require 'json'
|
||||
rescue
|
||||
require 'json/pure'
|
||||
end
|
||||
|
||||
Merb::Dispatcher
|
||||
|
||||
module Merb
|
||||
class Counter
|
||||
|
||||
attr_accessor :time
|
||||
def initialize
|
||||
@examples, @failures, @errors, @pending, @total_time = 0, 0, 0, 0, 0
|
||||
@err = ""
|
||||
@mutex = Mutex.new
|
||||
end
|
||||
|
||||
def failed?
|
||||
@failures > 0
|
||||
end
|
||||
|
||||
def add(spec, out, err)
|
||||
@mutex.synchronize do
|
||||
puts
|
||||
puts "Running #{spec}."
|
||||
STDOUT.puts out
|
||||
STDOUT.flush
|
||||
match = out.match(/(\d+) examples?, (\d+) failures?(?:, (\d+) errors?)?(?:, (\d+) pending?)?/m)
|
||||
time = out.match(/Finished in (\d+\.\d+) seconds/)
|
||||
@total_time += time[1].to_f if time
|
||||
if match
|
||||
e, f, errors, pending = match[1..-1]
|
||||
@examples += e.to_i
|
||||
@failures += f.to_i
|
||||
@errors += errors.to_i
|
||||
@pending += pending.to_i
|
||||
end
|
||||
unless err.chomp.empty?
|
||||
@err << err.chomp << "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def report
|
||||
i = 0
|
||||
@err.gsub!(/^\d*\)\s*/) do
|
||||
"#{i += 1})\n"
|
||||
end
|
||||
|
||||
puts @err
|
||||
puts
|
||||
if @failures != 0 || @errors != 0
|
||||
print "\e[31m" # Red
|
||||
elsif @pending != 0
|
||||
print "\e[33m" # Yellow
|
||||
else
|
||||
print "\e[32m" # Green
|
||||
end
|
||||
puts "#{@examples} examples, #{@failures} failures, #{@errors} errors, #{@pending} pending, #{sprintf("suite run in %3.3f seconds", @time.real)}"
|
||||
# TODO: we need to report pending examples all together
|
||||
puts "\e[0m"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require File.dirname(__FILE__) / "run_spec"
|
||||
|
||||
# Runs specs in all files matching the file pattern.
|
||||
#
|
||||
# ==== Parameters
|
||||
# globs<String, Array[String]>:: File patterns to look for.
|
||||
# spec_cmd<~to_s>:: The spec command. Defaults to "spec".
|
||||
# run_opts<String>:: Options to pass to spec commands, for instance,
|
||||
# if you want to use profiling formatter.
|
||||
# except<Array[String]>:: File paths to skip.
|
||||
def run_specs(globs, spec_cmd='spec', run_opts = "-c", except = [])
|
||||
require "optparse"
|
||||
require "spec"
|
||||
globs = globs.is_a?(Array) ? globs : [globs]
|
||||
|
||||
forking = (ENV["FORK"] ? ENV["FORK"] == "1" : Merb.forking_environment?)
|
||||
base_dir = File.expand_path(File.dirname(__FILE__) / ".." / ".." / "..")
|
||||
|
||||
counter = Merb::Counter.new
|
||||
forks = 0
|
||||
failure = false
|
||||
|
||||
FileUtils.rm_rf(File.join(base_dir, "results"))
|
||||
FileUtils.mkdir_p(File.join(base_dir, "results"))
|
||||
|
||||
time = Benchmark.measure do
|
||||
files = {}
|
||||
globs.each do |glob|
|
||||
Dir[glob].each do |spec|
|
||||
if forking
|
||||
Kernel.fork do
|
||||
run_spec(spec, base_dir)
|
||||
end
|
||||
Process.wait
|
||||
else
|
||||
`NOW=1 #{Gem.ruby} #{File.dirname(__FILE__) / "run_spec.rb"} \"#{spec}\"`
|
||||
end
|
||||
out = File.read(File.join(base_dir, "results", "#{File.basename(spec)}_out"))
|
||||
err = File.read(File.join(base_dir, "results", "#{File.basename(spec)}_err"))
|
||||
counter.add(spec, out, err)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Process.waitall
|
||||
|
||||
counter.time = time
|
||||
counter.report
|
||||
FileUtils.rm_rf(File.join(base_dir, "results"))
|
||||
exit!(counter.failed? ? -1 : 0)
|
||||
end
|
Loading…
Reference in New Issue