Chris@0: require 'rake' Chris@0: require 'rake/rdoctask' Chris@0: require 'tmpdir' Chris@0: Chris@0: task :default => :doc Chris@0: Chris@0: desc 'Generate documentation for the engines plugin.' Chris@0: Rake::RDocTask.new(:doc) do |doc| Chris@0: doc.rdoc_dir = 'doc' Chris@0: doc.title = 'Engines' Chris@0: doc.main = "README" Chris@0: doc.rdoc_files.include("README", "CHANGELOG", "MIT-LICENSE") Chris@0: doc.rdoc_files.include('lib/**/*.rb') Chris@0: doc.options << '--line-numbers' << '--inline-source' Chris@0: end Chris@0: Chris@0: desc 'Run the engine plugin tests within their test harness' Chris@0: task :cruise do Chris@0: # checkout the project into a temporary directory Chris@0: version = "rails_2.0" Chris@0: test_dir = "#{Dir.tmpdir}/engines_plugin_#{version}_test" Chris@0: puts "Checking out test harness for #{version} into #{test_dir}" Chris@0: `svn co http://svn.rails-engines.org/test/engines/#{version} #{test_dir}` Chris@0: Chris@0: # run all the tests in this project Chris@0: Dir.chdir(test_dir) Chris@0: load 'Rakefile' Chris@0: puts "Running all tests in test harness" Chris@0: ['db:migrate', 'test', 'test:plugins'].each do |t| Chris@0: Rake::Task[t].invoke Chris@0: end Chris@0: end Chris@0: Chris@0: task :clean => [:clobber_doc, "test:clean"] Chris@0: Chris@0: namespace :test do Chris@0: Chris@0: # Yields a block with STDOUT and STDERR silenced. If you *really* want Chris@0: # to output something, the block is yielded with the original output Chris@0: # streams, i.e. Chris@0: # Chris@0: # silence do |o, e| Chris@0: # puts 'hello!' # no output produced Chris@0: # o.puts 'hello!' # output on STDOUT Chris@0: # end Chris@0: # Chris@0: # (based on silence_stream in ActiveSupport.) Chris@0: def silence Chris@0: yield(STDOUT, STDERR) if ENV['VERBOSE'] Chris@0: streams = [STDOUT, STDERR] Chris@0: actual_stdout = STDOUT.dup Chris@0: actual_stderr = STDERR.dup Chris@0: streams.each do |s| Chris@0: s.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') Chris@0: s.sync = true Chris@0: end Chris@0: yield actual_stdout, actual_stderr Chris@0: ensure Chris@0: STDOUT.reopen(actual_stdout) Chris@0: STDERR.reopen(actual_stderr) Chris@0: end Chris@0: Chris@0: def test_app_dir Chris@0: File.join(File.dirname(__FILE__), 'test_app') Chris@0: end Chris@0: Chris@0: def run(cmd) Chris@0: cmd = cmd.join(" && ") if cmd.is_a?(Array) Chris@0: system(cmd) || raise("failed running '#{cmd}'") Chris@0: end Chris@0: Chris@0: desc 'Remove the test application' Chris@0: task :clean do Chris@0: FileUtils.rm_r(test_app_dir) if File.exist?(test_app_dir) Chris@0: end Chris@0: Chris@0: desc 'Build the test rails application (use RAILS=[edge,] to test against specific version)' Chris@0: task :generate_app do Chris@0: silence do |out, err| Chris@0: out.puts "> Creating test application at #{test_app_dir}" Chris@0: Chris@0: if ENV['RAILS'] Chris@0: vendor_dir = File.join(test_app_dir, 'vendor') Chris@0: FileUtils.mkdir_p vendor_dir Chris@0: Chris@0: if ENV['RAILS'] == 'edge' Chris@0: out.puts " Cloning Edge Rails from GitHub" Chris@0: run "cd #{vendor_dir} && git clone --depth 1 git://github.com/rails/rails.git" Chris@0: elsif ENV['RAILS'] =~ /\d\.\d\.\d/ Chris@0: if ENV['CURL'] Chris@0: out.puts " Cloning Rails Tag #{ENV['RAILS']} from GitHub using curl and tar" Chris@0: run ["cd #{vendor_dir}", Chris@0: "mkdir rails", Chris@0: "cd rails", Chris@0: "curl -s -L http://github.com/rails/rails/tarball/#{ENV['RAILS']} | tar xzv --strip-components 1"] Chris@0: else Chris@0: out.puts " Cloning Rails Tag #{ENV['RAILS']} from GitHub (can be slow - set CURL=true to use curl)" Chris@0: run ["cd #{vendor_dir}", Chris@0: "git clone git://github.com/rails/rails.git", Chris@0: "cd rails", Chris@0: "git pull", Chris@0: "git checkout v#{ENV['RAILS']}"] Chris@0: end Chris@0: elsif File.exist?(ENV['RAILS']) Chris@0: out.puts " Linking rails from #{ENV['RAILS']}" Chris@0: run "cd #{vendor_dir} && ln -s #{ENV['RAILS']} rails" Chris@0: else Chris@0: raise "Couldn't build test application from '#{ENV['RAILS']}'" Chris@0: end Chris@0: Chris@0: out.puts " generating rails default directory structure" Chris@0: run "ruby #{File.join(vendor_dir, 'rails', 'railties', 'bin', 'rails')} #{test_app_dir}" Chris@0: else Chris@0: version = `rails --version`.chomp.split.last Chris@0: out.puts " building rails using the 'rails' command (rails version: #{version})" Chris@0: run "rails #{test_app_dir}" Chris@0: end Chris@0: Chris@0: # get the database config and schema in place Chris@0: out.puts " writing database.yml" Chris@0: require 'yaml' Chris@0: File.open(File.join(test_app_dir, 'config', 'database.yml'), 'w') do |f| Chris@0: f.write(%w(development test).inject({}) do |h, env| Chris@0: h[env] = {"adapter" => "sqlite3", "database" => "engines_#{env}.sqlite3"} ; h Chris@0: end.to_yaml) Chris@0: end Chris@0: out.puts " installing exception_notification plugin" Chris@0: run "cd #{test_app_dir} && ./script/plugin install git://github.com/rails/exception_notification.git" Chris@0: end Chris@0: end Chris@0: Chris@0: # We can't link the plugin, as it needs to be present for script/generate to find Chris@0: # the plugin generator. Chris@0: # TODO: find and +1/create issue for loading generators from symlinked plugins Chris@0: desc 'Mirror the engines plugin into the test application' Chris@0: task :copy_engines_plugin do Chris@0: puts "> Copying engines plugin into test application" Chris@0: engines_plugin = File.join(test_app_dir, "vendor", "plugins", "engines") Chris@0: FileUtils.rm_r(engines_plugin) if File.exist?(engines_plugin) Chris@0: FileUtils.mkdir_p(engines_plugin) Chris@0: FileList["*"].exclude("test_app").each do |file| Chris@0: FileUtils.cp_r(file, engines_plugin) Chris@0: end Chris@0: end Chris@0: Chris@0: def insert_line(line, options) Chris@0: line = line + "\n" Chris@0: target_file = File.join(test_app_dir, options[:into]) Chris@0: lines = File.readlines(target_file) Chris@0: return if lines.include?(line) Chris@0: Chris@0: if options[:after] Chris@0: if options[:after].is_a?(String) Chris@0: after_line = options[:after] + "\n" Chris@0: else Chris@0: after_line = lines.find { |l| l =~ options[:after] } Chris@0: raise "couldn't find a line matching #{options[:after].inspect} in #{target_file}" unless after_line Chris@0: end Chris@0: index = lines.index(after_line) Chris@0: raise "couldn't find line '#{after_line}' in #{target_file}" unless index Chris@0: lines.insert(index + 1, line) Chris@0: else Chris@0: lines << line Chris@0: end Chris@0: File.open(target_file, 'w') { |f| f.write lines.join } Chris@0: end Chris@0: Chris@0: def mirror_test_files(src, dest=nil) Chris@0: destination_dir = File.join(*([test_app_dir, dest].compact)) Chris@0: FileUtils.cp_r(File.join(File.dirname(__FILE__), 'test', src), destination_dir) Chris@0: end Chris@0: Chris@0: desc 'Update the plugin and tests files in the test application from the plugin' Chris@0: task :mirror_engine_files => [:test_app, :copy_engines_plugin] do Chris@0: puts "> Tweaking generated application to be suitable for testing" Chris@0: Chris@0: # Replace the Rails plugin loader with the engines one. Chris@0: insert_line("require File.join(File.dirname(__FILE__), '../vendor/plugins/engines/boot')", Chris@0: :into => 'config/environment.rb', Chris@0: :after => "require File.join(File.dirname(__FILE__), 'boot')") Chris@0: Chris@0: # Add the engines test helper to handle fixtures & stuff. Chris@0: insert_line("require 'engines_test_helper'", :into => 'test/test_helper.rb') Chris@0: Chris@0: # Run engine plugin tests when running the application Chris@0: insert_line("task :test => ['test:engines:all']", :into => 'Rakefile') Chris@0: Chris@0: # We want exceptions to be raised Chris@0: insert_line("def rescue_action(e) raise e end;", Chris@0: :into => "app/controllers/application_controller.rb", Chris@0: :after => "class ApplicationController < ActionController::Base") Chris@0: Chris@0: # We need this method to test where actions are being rendered from. Chris@0: insert_line("include RenderInformation", Chris@0: :into => "app/controllers/application_controller.rb", Chris@0: :after => "class ApplicationController < ActionController::Base") Chris@0: Chris@0: puts "> Mirroring test application files into #{test_app_dir}" Chris@0: mirror_test_files('app') Chris@0: mirror_test_files('lib') Chris@0: mirror_test_files('plugins', 'vendor') Chris@0: mirror_test_files('unit', 'test') Chris@0: mirror_test_files('functional', 'test') Chris@0: end Chris@0: Chris@0: desc 'Prepare the engines test environment' Chris@0: task :test_app do Chris@0: version_tag = File.join(test_app_dir, 'RAILS_VERSION') Chris@0: existing_version = File.read(version_tag).chomp rescue 'unknown' Chris@0: if existing_version == ENV['RAILS'] Chris@0: puts "> Reusing existing test application (#{ENV['RAILS']})" Chris@0: else Chris@0: puts "> Recreating test application" Chris@0: Rake::Task["test:clean"].invoke Chris@0: Rake::Task["test:generate_app"].invoke Chris@0: Chris@0: File.open(version_tag, "w") { |f| f.write ENV['RAILS'] } Chris@0: end Chris@0: end Chris@0: end Chris@0: Chris@0: task :test => "test:mirror_engine_files" do Chris@0: puts "> Loading the test application environment and running tests" Chris@0: # We use exec here to replace the current running rake process Chris@0: exec("cd #{test_app_dir} && rake db:migrate && rake") Chris@0: end