rspec_base = File.expand_path(File.dirname(__FILE__) + '/../../rspec/lib')
$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
require 'spec/rake/spectask'
require 'spec/translator'

$TASK_ENV_NAMES = []

def prepare_for_test env_name
ActiveRecord::Base.establish_connection(:development)
db_specs = ActiveRecord::Base.configurations[env_name.to_s]
ActiveRecord::Base.connection.recreate_database(db_specs['database'])
ActiveRecord::Base.establish_connection(env_name)
ActiveRecord::Schema.verbose = true
`rake db:schema:load`
end

def spec_task_name for_env
"#{for_env}:parallel_spec"
end

{:models_test => :models, :controllers_test => :controllers,
:lib_test => [:extensions, :initializers, :rspec_extensions, :lib, :views, :helpers]}.each do |env, spec_dirs|
$TASK_ENV_NAMES << env
Spec::Rake::SpecTask.new(spec_task_name(env)) do |t|
t.spec_opts = ['--options', "\"#{RAILS_ROOT}/spec/spec.opts\""]
spec_paths = Array(spec_dirs).map { |spec_dir_name| "spec/#{spec_dir_name}/**/*_spec.rb" }
t.spec_files = FileList[*spec_paths]
t.fail_on_error = true
end
end

namespace :spec do
task :fast => ["db:migrate", "db:schema:dump"] do
env_dir = File.join(RAILS_ROOT, 'config', 'environments')

terminated_children = 0
process_success_vals = []

$TASK_ENV_NAMES.each do |env_name|
FileUtils.ln_s(File.join(env_dir, "test.rb"), File.join(env_dir, "#{env_name}.rb"), :force => true)
fork do
begin
RAILS_ENV = ENV['RAILS_ENV'] = env_name.to_s
prepare_for_test env_name
Rake::Task[spec_task_name(env_name)].invoke
ensure
FileUtils.rm_rf(File.join(env_dir, "#{env_name}.rb"))
end
end
end

loop do
Process.wait
terminated_children += 1
$?.success? || exit(-1)
(terminated_children == $TASK_ENV_NAMES.length) && exit(0)
end
end
end