lib/tasks/plugins_tests.rake
$broken_plugins = %w[
anti_spam
bsc
environment_notification
comment_classification
comment_group
ldap
solr
variables
]
@all_plugins = Dir.glob("plugins/*").map { |f| File.basename(f) } - ["template"]
@all_plugins.sort!
@all_tasks = [:units, :api, :functionals, :integration, :cucumber, :selenium]
def enabled_plugins
Dir.glob("{baseplugins,config/plugins}/*").map { |f| File.basename(f) } - ["README"]
end
@original_enabled_plugins = enabled_plugins
def disabled_plugins
@all_plugins - enabled_plugins
end
def enable_plugins(plugins)
plugins = Array(plugins)
command = ["./script/noosfero-plugins", "-q", "enable", *plugins]
puts plugins.join(" ")
Bundler.clean_system *command
end
def disable_plugins(plugins = "*")
if plugins == "*"
sh "./script/noosfero-plugins", "-q", "disableall"
else
plugins = Array(plugins)
sh "./script/noosfero-plugins", "-q", "disable", *plugins
end
end
def rollback_plugins_state
puts
puts "==> Rolling back plugins to their original states..."
disable_plugins
enable_plugins(@original_enabled_plugins)
end
task "db:test:plugins:prepare" do
if Dir.glob("config/plugins/*/db/migrate/*.rb").empty?
puts "I: skipping database setup, enabled plugins have no migrations"
else
Rake::Task["db:test:prepare"].execute
sh "rake db:migrate RAILS_ENV=test SCHEMA=/dev/null"
end
end
def plugin_name(plugin)
"#{plugin} plugin"
end
def plugin_enabled?(plugin)
File.exist?(File.join("config", "plugins", plugin)) || File.exist?(File.join("baseplugins", plugin))
end
def plugin_disabled_warning(plugin)
puts "E: you should enable #{plugin} plugin before running it's tests!"
end
def task2ext(task)
(task == :selenium || task == :cucumber) ? :feature : :rb
end
def task2profile(task, plugin)
if task == :cucumber
return plugin
elsif task == :selenium
return "#{plugin}_selenium"
else
return "default"
end
end
def filename2plugin(filename)
filename.split("/")[1]
end
def task2folder(task)
result = case task.to_sym
when :units
:unit
when :api
:api
when :functionals
:functional
when :integration
:integration
when :cucumber
:features
when :selenium
:features
end
return result
end
def run_test(name, files)
files = Array(files)
plugin = filename2plugin(files.first)
if name == :cucumber || name == :selenium
run_cucumber task2profile(name, plugin), files
else
run_minitest files
end
end
def run_minitest(files)
files = files.map { |f| File.join(Rails.root, f) }
sh "ruby", "-Itest", "-e ARGV.each{|f| require f}", *files
end
def run_cucumber(profile, files)
sh "ruby", "-S", "cucumber", "--profile", profile.to_s, "--format", ENV["CUCUMBER_FORMAT"] || "progress", *files
end
def custom_run(name, files, run = :all)
case run
when :all
run_test name, files
when :individually
files.each do |file|
run_test name, file
end
when :by_plugin
end
end
def run_tests(name, plugins, run = :all)
plugins = Array(plugins)
if name == :cucumber || name == :selenium
glob = "plugins/{#{plugins.join(',')}}/#{task2folder(name)}/**/*.#{task2ext(name)}"
else
glob = "plugins/{#{plugins.join(',')}}/test/#{task2folder(name)}/**/*.#{task2ext(name)}"
end
files = Dir.glob(glob)
if files.empty?
puts "I: no tests to run #{name}"
else
custom_run(name, files, run)
end
end
def test_sequence(plugins, tasks)
failed = {}
disable_plugins
plugins = @all_plugins if plugins == "*"
plugins = Array(plugins)
tasks = Array(tasks)
plugins.each do |plugin|
failed[plugin] = []
enable_plugins(plugin)
next if !plugin_enabled?(plugin)
begin
Rake::Task["db:test:plugins:prepare"].execute
rescue Exception => ex
failed[plugin] << :migration
end
tasks.each do |task|
begin
run_tests(task, plugin)
rescue Exception => ex
puts ex
failed[plugin] << task
end
end
disable_plugins
end
fail_flag = false
failed.each do |plugin, tasks|
unless tasks.empty?
puts "Tests failed on #{plugin} plugin: #{tasks.join(', ')}"
fail_flag = true
end
end
rollback_plugins_state
yield(failed) if block_given?
fail "There are broken tests to be fixed!" if fail_flag
end
def plugin_test_task(plugin, task, run = :all)
desc "Run #{task} tests for #{plugin_name(plugin)}"
task task do
test_sequence(plugin, task)
end
end
namespace :test do
namespace :noosfero_plugins do
@all_plugins.each do |plugin|
namespace plugin do
@all_tasks.each do |taskname|
plugin_test_task plugin, taskname
end
end
desc "Run all tests for #{plugin_name(plugin)}"
task plugin do
test_sequence([plugin], @all_tasks)
end
end
@all_tasks.each do |taskname|
desc "Run #{taskname} tests for all plugins"
task taskname do
test_sequence(@all_plugins - $broken_plugins, taskname)
end
end
end
desc "Run all tests for all plugins"
task :noosfero_plugins do
plugins = @all_plugins - $broken_plugins
if slice = ENV["SLICE"]
sel, size = slice.split "/"
size = (plugins.size / size.to_f).ceil
plugins = plugins.each_slice(size).to_a[sel.to_i - 1]
end
test_sequence plugins, @all_tasks do |failed|
plugins_status_report(failed)
end
end
end
def plugins_status_report(failed)
w = @all_plugins.map { |s| s.size }.max
puts
printf ("=" * (w + 21)) + "\n"
puts "Plugins status report"
printf ("=" * (w + 21)) + "\n"
printf "%-#{w}s %s\n", "Plugin", "Status"
printf ("-" * w) + " " + ("-" * 20) + "\n"
@all_plugins.each do |plugin|
if $broken_plugins.include?(plugin)
status = "BROKEN"
elsif failed[plugin].nil?
status = "SKIP"
elsif failed[plugin].empty?
status = "PASS"
else
status = "FAIL: #{failed[plugin].join(', ')}"
end
printf "%-#{w}s %s\n", plugin, status
end
printf ("=" * (w + 21)) + "\n"
puts
end