Permalink
Browse files

importing multi_rails from googlecode

git-svn-id: https://opensource.thinkrelevance.com/svn/multi_rails/trunk@52 fe6a39be-99a9-dc11-9a70-001c23e17821
  • Loading branch information...
0 parents commit ab771e5cc1cecfab97ec16a8f53cbefc6908dccb muness committed Jan 19, 2008
6 .autotest
@@ -0,0 +1,6 @@
+require 'autotest'
+$LOAD_PATH.unshift "test", "test/autotest"
+# Make sure autotest groks our directory structure to map tests to files
+Autotest.add_discovery do
+ ["railsplugin"]
+end
28 History.txt
@@ -0,0 +1,28 @@
+== 0.0.4
+
+* Change the all task so that the build will run through all rails versions, even if one of them fails, but at the end
+ the failing versions are printed and we abort. Thanks to Evan Weaver for initial patch and idea.
+* display the rails gem from the load path as a sanity check right after we gem/require
+* add autotest railsplugin discovery, so I can use autotest to test multi_rails
+* various rake tweaks to make release easier and more automated
+
+== 0.0.3
+
+* add support for using multi_rails with regular Rails apps, which was way more work then it should have been.
+* add the bootstrap task to add our multi_rails require line at the top of environment.rb in a rails app
+* renames vendor/rails to vendor/rails.off in a Rails app, in order to fall back to rubygems
+* added multi_rails_runner to allow multi_rails to set the RAILS_GEM_VERSION before the Rails Rakefile ever gets loaded
+* improve rdoc
+* move svn hosting to google code, to make it publicly accessible
+
+== 0.0.2 / Tuesday; October 23, 2007
+
+* first public release!
+* add link to email group
+* improve docs
+* add hook file to load rake tasks when used as a gem
+* change the env var for specifying the rails version under test to avoid name conflicts
+
+== 0.0.1 / Sunday; October 21, 2007
+
+* initial release, no public announcement
11 MIT-LICENSE
@@ -0,0 +1,11 @@
+Copyright (c) 2007 Relevance, Inc. (http://thinkrelevance.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 Manifest.txt
@@ -0,0 +1,27 @@
+.autotest
+History.txt
+MIT-LICENSE
+Manifest.txt
+README.txt
+Rakefile
+autotest.rb
+bin/multi_rails_runner.rb
+credits.txt
+install.rb
+lib/multi_rails.rb
+lib/multi_rails/config.rb
+lib/multi_rails/core_extensions.rb
+lib/multi_rails/loader.rb
+lib/multi_rails/multi_rails_error.rb
+lib/multi_rails/rails_app_helper.rb
+lib/multi_rails_init.rb
+tasks/load_multi_rails_rake_tasks.rb
+tasks/multi_rails.rake
+test/autotest/railsplugin.rb
+test/config_test.rb
+test/core_extensions_test.rb
+test/install_test.rb
+test/loader_test.rb
+test/multi_rails_init_test.rb
+test/multi_rails_test_helper.rb
+test/rails_app_helper_test.rb
114 README.txt
@@ -0,0 +1,114 @@
+#### MultiRails
+ by Relevance, http://thinkrelevance.com
+ Rob Sanheim - MultiRails lead
+
+MultiRails lets you test your Rails plugin or app against many versions of Rails in one sweep.
+
+#### DESCRIPTION:
+
+MultiRails allows easy testing against multiple versions of Rails for your Rails specific gem or plugin. It also has tentative support testing Rails applications against multiple versions of Rails.
+
+Use MultiRails to hook in Rails 2.0 testing in your continuous integration. Still working on Rails 2.0 support? Use MultiRails to see where your test suite falls down against the latest and greatest versions of Rails.
+
+MultiRails was initially developed by members of Relevance while developing Streamlined against edge Rails. To see how Streamlined uses MultiRails, go to http://trac.streamlinedframework.org.
+
+#### FEATURES:
+
+* easily test plugins/extensions using a require from your test_helper.rb and a require in your RakeFile
+* rake tasks to test against a specified version of Rails, the latest version, or all versions
+* tentative support for testing plain Rails apps against multiple versions of Rails
+* Uses rubygems for version management of Rails
+
+#### TODOs:
+
+* improve docs on how to override what files are required by multi_rails
+* maybe add ability to load plain Rails versions -- ie checked out copies not in RubyGems
+
+#### NOTES:
+
+* (__For Rails apps only__) multi_rails will rename your vendor/rails directory to vendor/rails.off if it finds one within your rails app. We have to do this to make Rails fall back to RubyGems rails. Multi_rails will rename back to the correct vendor/rails when done testing, so it will not interrupt your app in normal use.
+* (__For Rails apps only__) multi_rails needs to add a line to top of your environment.rb to hook into -- see the instructions below for more details
+
+#### REQUIREMENTS:
+
+* Ruby 1.8.5 or higher
+* Rubygems
+* Rails 1.2.1 or higher
+* at least one copy of Rails installed via rubygems.
+
+#### INSTALLING FOR RAILS APPS
+
+* install the plugin, which will copy the multi_rails_runner into your script folder on install.
+ script/plugin install http://opensource.thinkrelevance.com/svn/multi_rails/tags/stable/multi_rails
+
+* Run the multi_rails bootstrap command to get your Rails app ready to go with multi_rails - this will add a require line to the top of your environment.rb needed for multi_rails to work right.
+ script/multi_rails_runner bootstrap
+
+* Run your tests against all versions of Rails installed (the default):
+ script/multi_rails_runner
+ or run our tests against the most recent version of Rails you have installed:
+ script/multi_rails_runner latest
+ or just a specific version:
+ MULTIRAILS_RAILS_VERSION=1.2.5 script/multi_rails_runner one
+
+#### INSTALLING FOR PLUGINS
+
+* Install multi_rails
+ sudo gem install multi_rails
+
+* In your projects Rakefile, require the multi_rails Rake tasks.
+
+ require "load_multi_rails_rake_tasks"
+
+* Run rake -T to verify you see the multi_rails tasks.
+ rake -T multi_rails
+ # should see "rake test:multi_rails:all, rake test:multi_rails:latest...etc"
+
+* In your test_helper, require multi_rails_init *before* any rails specific requires (activerecord, actioncontroller, activesupport, etc).
+
+ require 'multi_rails_init'
+
+* Run the multi_rails:all rake task to run your test suite against all versions of Rails you have installed via gems. Install other versions of Rails using rubygems to add them to your test suite.
+
+* For changing the Rails version under test, set the environment variable MULTIRAILS_RAILS_VERSION to version you want, and run the multi_rails:one task or just run a test class directly.
+
+#### HELP
+
+* Join the mailing list! - http://groups.google.com/group/multi_rails
+
+* Rails plugin testing is pretty solid, but rails *app* testing is still new. Post issues to the mailing list.
+* Getting gem activation errors? Post to the list with how you are using multi_rails, and I'll try to help.
+
+#### URLs
+
+* rubyforge home - http://rubyforge.org/projects/multi-rails/
+* rdocs - http://multi-rails.rubyforge.org/
+* mailing list - http://groups.google.com/group/multi_rails
+
+* svn stable - http://robsanheim.googlecode.com/svn/tags/stable/multi_rails (gem is released from here)
+* svn trunk - http://robsanheim.googlecode.com/svn/trunk/multi_rails
+
+#### LICENSE:
+
+(The MIT License)
+
+Copyright (c) 2007 Relevance, http://thinkrelevance.com
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 Rakefile
@@ -0,0 +1,56 @@
+require 'rubygems'
+require 'hoe'
+require File.expand_path(File.join(File.dirname(__FILE__), "/lib/multi_rails"))
+load File.expand_path(File.join(File.dirname(__FILE__), "/tasks/multi_rails.rake"))
+
+Hoe.new('multi_rails', MultiRails::VERSION) do |p|
+ p.rubyforge_name = 'multi-rails'
+ p.author = 'Relevance'
+ p.email = 'multi_rails@googlegroups.com'
+ p.summary = 'Testing tool to easily test agaist multiple versions of Rails.'
+ p.description = p.paragraphs_of('README.txt', 0..10).join("\n\n")
+ p.url = 'http://multi-rails.rubyforge.org/'
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
+ p.remote_rdoc_dir = '' # Release to root
+ p.test_globs = 'test/**/*_test.rb' # we use the foo_test convention
+ p.spec_extras[:require_paths] = ['lib', 'tasks']
+end
+
+desc "Copy trunk to stable tag in SVN to make things easy for Rails plugin installation."
+task :copy_stable do
+ trunk_dir = "~/src/opensource/robsanheim/trunk/multi_rails/"
+ stable_dir = "~/src/opensource/robsanheim/tags/stable/multi_rails/"
+ puts %x[rsync --exclude='.svn' -r #{trunk_dir} #{stable_dir}]
+ puts %x[svn ci #{stable_dir} -m 'Release to stable from trunk.']
+end
+
+desc "Convert the readme from markdown to html to prep for posting on blog/email/whatever."
+task :email_to_html => :email do
+ require 'redcloth'
+ RedCloth::DEFAULT_RULES.replace [:markdown, :textile]
+
+ email = File.read("email.txt")
+ html = RedCloth.new(email).to_html
+ html = text_helper.auto_link(html)
+ File.open("email.html", "w") do |f|
+ f << html
+ end
+end
+
+desc "Do a full release of the multi_rails, including copying to stable tag, pushing docs and prepping for blog/annoucement."
+task :full_release => [:require_version, :copy_stable, :publish_docs, :email_to_html, :release]
+
+desc "Must supply the VERSION env var"
+task :require_version do
+ raise "You must supply a VERSION=x.x.x environment var to release!" unless ENV["VERSION"]
+end
+
+# it should be easier then this to do some g'd autolinking
+def text_helper
+ gem 'actionpack'
+ require 'action_controller' # bringing this in for autolinks
+ helper = Object.new
+ helper.extend ActionView::Helpers::TextHelper
+ helper.extend ActionView::Helpers::TagHelper
+ helper
+end
1 autotest.rb
32 bin/multi_rails_runner.rb
@@ -0,0 +1,32 @@
+#!/usr/bin/env ruby
+require 'rake'
+require 'rake/testtask'
+require 'pathname'
+
+# Get the real path, to make sure if this file is symlinked we don't mess up
+absolute_current_dir = File.dirname(Pathname.new(__FILE__).realpath)
+
+require File.expand_path(File.join(absolute_current_dir, "../lib/multi_rails"))
+require File.expand_path(File.join(absolute_current_dir, "../tasks/load_multi_rails_rake_tasks"))
+
+# A script to allow multi_rails to work with Rails apps
+# For testing Rails plugins or gems, you don't need to use this - you can just the rake tasks.
+module MultiRails
+ module Runner
+ # Run multi_rails using the specified task, defaults to testing against all Rails versions intalled
+ def self.run(task = "all")
+ task = task ? task : "all"
+ puts %[Running MultiRails with task "#{task}"...]
+ MultiRails::RailsAppHelper.run(task)
+ end
+
+ end
+end
+
+HELP_MESSAGE = "Give this runner the name of the multi_rails rake task you want to run, or give it no args if you want the default behavior of testing against all versions of Rails."
+
+if ARGV.size > 1
+ puts HELP_MESSAGE
+else
+ MultiRails::Runner.run(ARGV.first)
+end
3 credits.txt
@@ -0,0 +1,3 @@
+Thanks to:
+
+Evan Weaver
15 install.rb
@@ -0,0 +1,15 @@
+require 'fileutils'
+
+BAR = "=" * 80
+RUNNER_PATH = "script/multi_rails_runner"
+ACTUAL_PATH = File.expand_path(File.join(RAILS_ROOT, "/vendor/plugins/multi_rails/bin/multi_rails_runner.rb"))
+
+puts BAR
+puts "Installing multi_rails, and settig up /script/multi_rails_runner."
+
+FileUtils.symlink(ACTUAL_PATH, RUNNER_PATH, :force => true)
+`chmod +x #{RAILS_ROOT}/script/multi_rails_runner`
+puts "Run '#{RUNNER_PATH} bootstrap' to add the necessary multi_rails require line to the top of your environment.rb file."
+puts "Once that has been done, run '#{RUNNER_PATH}' from the root of our project to test your Rails app against all your versions of Rails."
+puts "Happy Testing !"
+puts BAR
15 lib/multi_rails.rb
@@ -0,0 +1,15 @@
+require 'rubygems'
+require 'logger'
+files = %w(core_extensions config loader multi_rails_error rails_app_helper)
+files.each do |file|
+ require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails/#{file}"))
+end
+
+module MultiRails
+ VERSION = '0.0.4'
+ BAR = "=" * 80 # BEST CONSTANT EVAH
+
+ def self.gem_and_require_rails
+ Loader.gem_and_require_rails
+ end
+end
38 lib/multi_rails/config.rb
@@ -0,0 +1,38 @@
+module MultiRails
+
+ # Simple config object
+ class Config
+ @weird_versions = { "2.0.0.PR" => "1.2.4.7794" }
+ @rails_requires = %w[active_support
+ active_record
+ action_controller
+ action_controller/test_process]
+
+ class << self
+ attr_accessor :weird_versions, :rails_requires
+ def version_lookup(version = nil)
+ return named_version_lookup(version) if version
+ return named_version_lookup(ENV["MULTIRAILS_RAILS_VERSION"]) if ENV['MULTIRAILS_RAILS_VERSION']
+ Loader.latest_stable_version
+ end
+
+ def named_version_lookup(version)
+ version = @weird_versions[version] || version
+ raise MultiRailsError, "Can't find Rails gem version #{version} - available versions are: #{Loader.all_rails_versions.to_sentence})." if !Loader.all_rails_versions.include? version
+ version
+ end
+
+ # Output rails from the load path as a sanity check, to make sure we are really using the version of Rails we think we are
+ def rails_load_path
+ gem_rails_regex = %r[gems/(rails-[\d\.]+)/]
+ load_path.grep(gem_rails_regex).first.match(gem_rails_regex)[1] rescue nil
+ end
+
+ def load_path
+ $LOAD_PATH
+ end
+
+ end
+ end
+
+end
44 lib/multi_rails/core_extensions.rb
@@ -0,0 +1,44 @@
+# Add some nice to haves from ActiveSupport
+
+module Kernel
+ def silence_warnings
+ old_verbose, $VERBOSE = $VERBOSE, nil
+ yield
+ ensure
+ $VERBOSE = old_verbose
+ end
+end
+
+module HashExtensions
+ def reverse_merge(other_hash)
+ other_hash.merge(self)
+ end
+
+ def reverse_merge!(other_hash)
+ replace(reverse_merge(other_hash))
+ end
+end
+
+module ArrayExtensions
+ # Converts the array to comma-seperated sentence where the last element is joined by the connector word. Options:
+ # * <tt>:connector</tt>: The word used to join the last element in arrays with two or more elements (default: "and")
+ # * <tt>:skip_last_comma</tt>: Set to true to return "a, b and c" instead of "a, b, and c".
+ def to_sentence(options = {})
+ options.reverse_merge! :connector => 'and', :skip_last_comma => false
+
+ case length
+ when 0
+ ""
+ when 1
+ self[0]
+ when 2
+ "#{self[0]} #{options[:connector]} #{self[1]}"
+ else
+ "#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]} #{self[-1]}"
+ end
+ end
+
+end
+
+Array.send(:include, ArrayExtensions) unless Array.respond_to?(:to_sentence)
+Hash.send(:include, HashExtensions) unless Hash.respond_to?(:reverse_merge) && Hash.respond_to?(:reverse_merge!)
63 lib/multi_rails/loader.rb
@@ -0,0 +1,63 @@
+module MultiRails
+
+ class Loader
+ attr_reader :version
+
+ def self.logger
+ @logger ||= Logger.new(STDOUT)
+ end
+
+ # Require and gem rails
+ # Will use a default version if none is supplied
+ def self.gem_and_require_rails(rails_version = nil)
+ rails_version = MultiRails::Config.version_lookup(rails_version)
+ Loader.new(rails_version).gem_and_require_rails
+ end
+
+ # Returns a list of all Rails versions available, oldest first
+ def self.all_rails_versions
+ specs = Gem::cache.find_name("rails")
+ specs.map {|spec| spec.version.to_s }.sort
+ end
+
+ # Try to detech the latest stable by finding the most recent version with less then 4 version parts
+ # -- not sure if there is a better way?
+ def self.latest_stable_version
+ all_rails_versions.sort.reverse.detect {|version| version.count(".") < 3 }
+ end
+
+ # Find the most recent version
+ def self.latest_version
+ all_rails_versions.sort.last
+ end
+
+ # A version of the loader is created to gem and require one version of Rails
+ def initialize(version)
+ @version = version
+ end
+
+ # Gem a version of Rails, and require appropriate files
+ def gem_and_require_rails
+ gem_rails
+ require_rails
+ display_rails_gem_used
+ end
+
+ # Display the rails gem from the laod path, as a sanity check to make sure we are getting the rails version we expect
+ def display_rails_gem_used
+ puts %[#{MultiRails::BAR}\nUsing rails gem: #{Config.rails_load_path}\n]
+ end
+
+ def gem_rails
+ gem 'rails', version
+ rescue LoadError => e
+ msg = %Q[Cannot find gem for Rails version: '#{version}'!\nInstall the missing gem with:\nsudo gem install -v=#{version} rails]
+ raise MultiRailsError, msg
+ end
+
+ def require_rails
+ Config.rails_requires.each {|lib| require lib }
+ end
+ end
+
+end
2 lib/multi_rails/multi_rails_error.rb
@@ -0,0 +1,2 @@
+class MultiRailsError < RuntimeError
+end
108 lib/multi_rails/rails_app_helper.rb
@@ -0,0 +1,108 @@
+require 'rake'
+module MultiRails
+ module RailsAppHelper
+ RAILS_DIRECTORIES = %w(app config public test)
+ REQUIRE_LINE = %[require File.expand_path('config/rails_version') if File.exist?("config/rails_version.rb")].freeze
+
+ class << self
+
+ # Run the appropriate task or method for MultiRails
+ # This is called from the MultiRails command line runner
+ def run(task)
+ if task == "bootstrap"
+ self.bootstrap_for_rails
+ else
+ ENV["MULTIRAILS_FOR_RAILS_APP"] = "true"
+ Rake::Task["test:multi_rails:#{task}"].invoke
+ end
+ end
+
+ # Do a one time bootstrap to let MultiRails do its thing -- we aren't putting this
+ # in the general MultiRails rake file to keep it from showing up in contexts where
+ # it doesn't make sense (ie when testing a plugin).
+ def bootstrap_for_rails
+ set_rails_root
+ add_require_line_to_environment_file
+ end
+
+ # Make sure we have RAILS_ROOT set - will try to find it dynamically if its not set.
+ def set_rails_root
+ if Object.const_defined?("RAILS_ROOT")
+ RAILS_ROOT
+ else
+ Object.const_set("RAILS_ROOT", find_rails_root_dir)
+ end
+ raise("Must have a valid RAILS_ROOT.") unless Object.const_defined?("RAILS_ROOT") && RAILS_ROOT
+ RAILS_ROOT
+ end
+
+ def clean_up
+ FileUtils.rm(rails_gem_version_file) if within_rails_app? && File.exist?(rails_gem_version_file)
+ rename_vendor_rails_to_original
+ end
+
+ def init_for_rails_app(version)
+ set_rails_root
+ write_rails_gem_version_file(version)
+ rename_vendor_rails_if_necessary
+ end
+
+ def find_rails_root_dir
+ if current_dir_contains_rails_dirs? then Dir.pwd end
+ end
+
+ def current_dir_contains_rails_dirs?
+ if RAILS_DIRECTORIES.all? { |rails_dir| Dir.entries(Dir.pwd).include?(rails_dir) }
+ Dir.pwd
+ end
+ end
+
+ # Write out a file which is loaded later, so that the RAILS_GEM_VERSION gets set in the correct process
+ def write_rails_gem_version_file(version)
+ File.open(rails_gem_version_file, 'w') do |file|
+ file << %|RAILS_GEM_VERSION = '#{version}' unless Object.const_defined?("RAILS_GEM_VERSION")|
+ end
+ end
+
+ def rails_gem_version_file
+ File.expand_path("#{RAILS_ROOT}/config/rails_version.rb")
+ end
+
+ def rename_vendor_rails_if_necessary
+ File.rename(vendor_rails, vendor_rails_off) if File.directory?(vendor_rails)
+ end
+
+ def rename_vendor_rails_to_original
+ File.rename(vendor_rails_off, vendor_rails) if File.directory?(vendor_rails_off)
+ end
+
+ def add_require_line_to_environment_file
+ raise MultiRailsError, "Can't find environment.rb file was looking at path: #{environment_file}" unless File.exist?(environment_file)
+ unless first_environment_line == REQUIRE_LINE
+ original_content = File.read(environment_file)
+ File.open(environment_file, 'r+') do |f|
+ f.puts REQUIRE_LINE
+ f.print original_content
+ end
+ end
+ end
+
+ def first_environment_line
+ File.open(environment_file).readline.strip
+ end
+
+ def environment_file
+ File.expand_path(File.join(RAILS_ROOT, "config/environment.rb"))
+ end
+
+ def vendor_rails
+ "#{RAILS_ROOT}/vendor/rails"
+ end
+
+ def vendor_rails_off
+ "#{RAILS_ROOT}/vendor/rails.off"
+ end
+ end
+
+ end
+end
3 lib/multi_rails_init.rb
@@ -0,0 +1,3 @@
+# We include an init file here to be easily required using a gemmed version of MultiRails
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails"))
+MultiRails::gem_and_require_rails
1 tasks/load_multi_rails_rake_tasks.rb
@@ -0,0 +1 @@
+load File.expand_path(File.join(File.dirname(__FILE__), "multi_rails.rake"))
91 tasks/multi_rails.rake
@@ -0,0 +1,91 @@
+require 'rubygems'
+require 'rake'
+require 'rake/testtask'
+require File.expand_path(File.join(File.dirname(__FILE__), "/../lib/multi_rails"))
+
+# Enable overriding the already invoked flag of a Rake task
+class Rake::Task
+ attr_accessor :already_invoked
+end
+
+namespace :test do
+ namespace :multi_rails do
+
+ desc "Run against all installed versions of Rails. Local versions found: [#{MultiRails::Loader.all_rails_versions.to_sentence}]."
+ task :all do
+ begin
+ failed_versions = []
+ MultiRails::Loader.all_rails_versions.each_with_index do |version, index|
+ silence_warnings { ENV["MULTIRAILS_RAILS_VERSION"] = version }
+ init_for_rails_app(version) if within_rails_app?
+ print_rails_version
+ reset_test_tasks unless index == 0
+ begin
+ Rake::Task[:test].invoke
+ rescue RuntimeError => e
+ puts e.message
+ failed_versions << version
+ end
+ end
+ abort("Build failed with Rails versions: [#{failed_versions.to_sentence}].") if failed_versions.any?
+ ensure
+ clean_up
+ end
+ end
+
+ desc "Run against one verison of Rails specified as 'MULTIRAILS_RAILS_VERSION' - for example 'rake test:multi_rails:one MULTIRAILS_RAILS_VERSION=1.2.3'"
+ task :one do
+ begin
+ version = ENV["MULTIRAILS_RAILS_VERSION"]
+ raise "Must give a version number" unless version
+ init_for_rails_app(version) if within_rails_app?
+ print_rails_version
+ Rake::Task[:test].invoke
+ ensure
+ clean_up
+ end
+ end
+
+ desc "Run against the most recent version of Rails installed. Most recent found: [#{MultiRails::Loader.latest_version}]."
+ task :latest do
+ begin
+ version = MultiRails::Loader.latest_version
+ ENV["MULTIRAILS_RAILS_VERSION"] = version
+ init_for_rails_app(version) if within_rails_app?
+ print_rails_version
+ Rake::Task[:test].invoke
+ ensure
+ clean_up
+ end
+ end
+
+ def init_for_rails_app(version)
+ MultiRails::RailsAppHelper.init_for_rails_app(version)
+ load "Rakefile"
+ end
+
+ def within_rails_app?
+ ENV["MULTIRAILS_FOR_RAILS_APP"] == "true"
+ end
+
+ # clean up after ourselves, reverting to clean state if needed
+ def clean_up
+ MultiRails::RailsAppHelper.clean_up if within_rails_app?
+ end
+
+ def print_rails_version
+ puts "\n#{MultiRails::BAR}\nTesting with Rails #{MultiRails::Config.version_lookup}\n#{MultiRails::BAR}"
+ end
+
+ # Need to hack the Rake test task a bit, otherwise it will only run once and never repeat.
+ def reset_test_tasks
+ ["test", "test:units", "test:functionals", "test:integration"].each do |name|
+ if Rake::Task.task_defined?(name)
+ Rake::Task[name].already_invoked = false
+ Rake::Task[name].prerequisites.each {|p| Rake::Task[p].already_invoked = false}
+ end
+ end
+ end
+
+ end
+end
35 test/autotest/railsplugin.rb
@@ -0,0 +1,35 @@
+# Discover our lib and tests for autotest'ing Rails Plugins
+class Autotest::Railsplugin < Autotest
+ def initialize
+ super
+ @exceptions = /\/\./
+ @test_mappings = {
+ /^lib\/(.*)\.rb$/ => proc { |filename, m|
+ # p "match #{m[1]}"
+ file = File.basename(filename).gsub("_", "_?").gsub(".rb", "")
+ foo = files_matching %r%^test/.*#{file}_test.rb$%
+ # p "the file: #{file}"
+ # p "the regex: #{files_matching %r%^test/.*#{file}_test.rb$%}"
+ # p "files_matching: #{foo}"
+ foo
+ },
+ /^test\/.*_test\.rb$/ => proc { |filename, _|
+ filename
+ }
+ }
+ end
+
+ def files_matching regexp
+ # puts @files.sort.inspect
+ @files.keys.select { |k|
+ k =~ regexp
+ }
+ end
+
+ # def files_matching regexp
+ # @files.keys.select { |k|
+ # k =~ regexp
+ # }
+ # end
+
+end
54 test/config_test.rb
@@ -0,0 +1,54 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "Version Lookup in config" do
+
+ it "should use argument version if passed in " do
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3", "1.2.4"])
+ MultiRails::Config.version_lookup("1.2.3").should == "1.2.3"
+ end
+
+ it "should use env var if set" do
+ begin
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.99"])
+ ENV["MULTIRAILS_RAILS_VERSION"] = "1.2.99"
+ MultiRails::Config.version_lookup.should == "1.2.99"
+ ensure
+ silence_warnings { ENV["MULTIRAILS_RAILS_VERSION"] = nil }
+ end
+ end
+
+ it "should raise if providing env var and we dont find a corresponding version" do
+ begin
+ ENV["MULTIRAILS_RAILS_VERSION"] = "X.X.99"
+ lambda { MultiRails::Config.version_lookup }.should.raise(MultiRailsError)
+ ensure
+ silence_warnings { ENV["MULTIRAILS_RAILS_VERSION"] = nil }
+ end
+ end
+
+ it "should use latest stable version if there is no argumnt or env var" do
+ MultiRails::Config.version_lookup.should == MultiRails::Loader.latest_stable_version
+ end
+end
+
+describe "getting the rails load path " do
+ it "should grab only the real rails paths, and ignore false rails directories in the load path" do
+ load_path = ["/Users/rsanheim/src/relevance/essi/trunk/essi/vendor/plugins/test_spec_on_rails/lib",
+ "/Users/rsanheim/src/relevance/essi/trunk/essi/vendor/plugins/rails_env/lib",
+ "/opt/local/lib/ruby/gems/1.8/gems/rails-2.0.1/lib/../builtin/rails_info/", "/opt/local/lib/ruby/gems/1.8/gems/rails-2.0.1/lib",
+ "/opt/local/lib/ruby/gems/1.8/gems/rails-2.0.1/bin", "/Users/rsanheim/src/project/trunk/foo/vendor/gems/rails_env-0.4.0/lib"]
+ MultiRails::Config.stubs(:load_path).returns(load_path)
+ MultiRails::Config.rails_load_path.should == "rails-2.0.1"
+ end
+
+ it "should use the real load path" do
+ MultiRails::Config.load_path.should == $LOAD_PATH
+ end
+
+ it "should return nil if we can't figure out the rails version" do
+ load_path = ["/Users/rsanheim/src/relevance/essi/trunk/essi/vendor/plugins/test_spec_on_rails/lib",
+ "/Users/rsanheim/src/relevance/essi/trunk/essi/vendor/plugins/rails_env/lib"]
+ MultiRails::Config.stubs(:load_path).returns(load_path)
+ MultiRails::Config.rails_load_path.should == nil
+ end
+end
7 test/core_extensions_test.rb
@@ -0,0 +1,7 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "core extensions" do
+ it "should extend Kernel" do
+ Kernel.should.respond_to? :silence_warnings
+ end
+end
29 test/install_test.rb
@@ -0,0 +1,29 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "install hook" do
+ setup { Object.const_set("RAILS_ROOT", "/src/rails_app") }
+ teardown { Object.send(:remove_const, "RAILS_ROOT") if Object.const_defined?("RAILS_ROOT")}
+
+ def load_install
+ silence_warnings do
+ load File.expand_path(File.join(File.dirname(__FILE__), "../install.rb"))
+ end
+ end
+
+ it "should copy the multi_rails_runner to the script directory" do
+ Object.any_instance.stubs(:puts).returns(nil)
+ Object.any_instance.stubs(:`)
+
+ FileUtils.expects(:symlink).with("#{RAILS_ROOT}/vendor/plugins/multi_rails/bin/multi_rails_runner.rb",
+ "script/multi_rails_runner", :force => true)
+ load_install
+ end
+
+ it 'should make the file executable' do
+ Object.any_instance.stubs(:puts).returns(nil)
+ Object.any_instance.expects(:`).with("chmod +x #{RAILS_ROOT}/script/multi_rails_runner")
+ File.stubs(:symlink)
+ load_install
+ end
+
+end
94 test/loader_test.rb
@@ -0,0 +1,94 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "loader" do
+
+ setup do
+ never_really_require_rails
+ never_puts
+ end
+
+ it "should fall back to a default version to try" do
+ MultiRails::Loader.any_instance.stubs(:display_rails_gem_used)
+ stub_rails_requires
+ MultiRails::Loader.any_instance.expects(:gem).with("rails", MultiRails::Loader.latest_stable_version)
+ MultiRails::Loader.gem_and_require_rails
+ end
+
+ it "should fail fast if we are missing a requested gem version" do
+ lambda { MultiRails::Loader.gem_and_require_rails("9.9.9") }.should.raise(MultiRailsError)
+ end
+
+ it "should gem the specified version" do
+ MultiRails::Loader.any_instance.stubs(:display_rails_gem_used)
+ stub_rails_requires
+ MultiRails::Loader.any_instance.expects(:gem).with("rails", "1.2.5").returns(true)
+ MultiRails::Loader.gem_and_require_rails("1.2.5")
+ end
+
+ it "should allow using a better name for weird gem version numbers, like 2.0.0 PR => 1.2.4.7794" do
+ MultiRails::Loader.any_instance.stubs(:display_rails_gem_used)
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3", "1.2.4", "1.2.4.7794"])
+ stub_rails_requires
+ MultiRails::Loader.any_instance.expects(:gem).with("rails", MultiRails::Config.weird_versions["2.0.0.PR"]).returns(true)
+ MultiRails::Loader.gem_and_require_rails("2.0.0.PR")
+ end
+
+ it "should require the needed dependancies" do
+ MultiRails::Loader.any_instance.stubs(:display_rails_gem_used)
+ MultiRails::Loader.any_instance.stubs(:gem)
+ MultiRails::Config.rails_requires.each do |file|
+ MultiRails::Loader.any_instance.expects(:require).with(file)
+ end
+ MultiRails::Loader.gem_and_require_rails
+ end
+
+ def stub_rails_requires
+ MultiRails::Loader.any_instance.stubs(:require).returns(true)
+ end
+
+ def never_really_require_rails
+ MultiRails::Loader.any_instance.expects(:require).never
+ end
+
+end
+
+describe "finding all gems of rails available" do
+
+ it "should find rails by name when retrieving all rails versions, in order to avoid false positives with other gems with rails in the name" do
+ Gem::cache.expects(:find_name).with("rails").returns([])
+ MultiRails::Loader.all_rails_versions
+ end
+
+ it "should return all Rails versions it finds sorted with the earliest versions first" do
+ specs = [stub(:version => stub(:to_s => "1.2.4")), stub(:version => stub(:to_s => "1.2.3"))]
+ Gem::cache.expects(:find_name).with("rails").returns(specs)
+ MultiRails::Loader.all_rails_versions.should == ["1.2.3", "1.2.4"]
+ end
+
+end
+
+describe "finding latest stable version" do
+ it "should find the latest stable rails gem" do
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3", "1.2.5", "1.2.5.1343"])
+ MultiRails::Loader.latest_stable_version.should == "1.2.5"
+ end
+
+ it "should find 2.0.0 when its released" do
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3", "1.2.5", "1.2.5.1343", "2.0.0", "1.2.7"])
+ MultiRails::Loader.latest_stable_version.should == "2.0.0"
+ end
+
+end
+
+describe "finding latest version" do
+ it "should find the most recent version, regardless of edge or non edge versions" do
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3", "1.2.5", "1.2.5.1343"])
+ MultiRails::Loader.latest_version.should == "1.2.5.1343"
+ end
+
+ it "should return the only version you have if there is only one installed" do
+ MultiRails::Loader.stubs(:all_rails_versions).returns(["1.2.3"])
+ MultiRails::Loader.latest_version.should == "1.2.3"
+ end
+
+end
18 test/multi_rails_init_test.rb
@@ -0,0 +1,18 @@
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "Rubygem test helper init" do
+ setup { never_puts }
+
+ it "should call gem and require rails" do
+ MultiRails.expects(:gem_and_require_rails).once
+ load File.expand_path(File.join(File.dirname(__FILE__), "../lib/multi_rails_init.rb"))
+ end
+
+ it "should actually do the gem and require" do
+ MultiRails::Loader.any_instance.expects(:require).never
+ MultiRails::Loader.any_instance.expects(:gem_rails)
+ MultiRails::Loader.any_instance.expects(:require_rails)
+ load File.expand_path(File.join(File.dirname(__FILE__), "../lib/multi_rails_init.rb"))
+ end
+
+end
13 test/multi_rails_test_helper.rb
@@ -0,0 +1,13 @@
+require 'test/unit'
+require 'test/spec'
+require 'mocha'
+require 'redgreen' unless Object.const_defined?("TextMate")
+
+require File.expand_path(File.join(File.dirname(__FILE__), "../lib/multi_rails"))
+
+class Test::Unit::TestCase
+ def never_puts
+ MultiRails::Loader.stubs(:puts)
+ MultiRails::Loader.any_instance.stubs(:puts)
+ end
+end
131 test/rails_app_helper_test.rb
@@ -0,0 +1,131 @@
+require 'tempfile'
+require File.expand_path(File.join(File.dirname(__FILE__), "multi_rails_test_helper"))
+
+describe "running a task" do
+ setup { Object.const_set("RAILS_ROOT", "/src/rails_app")}
+ teardown { Object.send(:remove_const, "RAILS_ROOT")}
+
+ it "should call the bootstrap method if thats the task" do
+ MultiRails::RailsAppHelper.expects(:bootstrap_for_rails)
+ MultiRails::RailsAppHelper.run('bootstrap')
+ end
+
+ it "should invoke the corresponding rake task for any other arg" do
+ task = mock().expects(:invoke)
+ Rake::Task.expects(:[]).with("test:multi_rails:all").returns(task)
+ MultiRails::RailsAppHelper.run('all')
+ end
+
+end
+
+describe "determing rails root" do
+ teardown { Object.send(:remove_const, "RAILS_ROOT") if Object.const_defined?("RAILS_ROOT")}
+
+ it "should try the RAILS_ROOT constant first" do
+ Object.const_set("RAILS_ROOT", "/src/rails_app")
+ MultiRails::RailsAppHelper.set_rails_root.should == "/src/rails_app"
+ end
+
+ it "should fallback to finding it dynamically" do
+ current_dir_stub = "/foo/bar/my_rails_app"
+ Dir.expects(:entries).returns(["app", "lib", "config", "public", "test", "vendor"]).at_least_once
+ Dir.expects(:pwd).returns(current_dir_stub).at_least_once
+ MultiRails::RailsAppHelper.set_rails_root.should == "/foo/bar/my_rails_app"
+ end
+
+ it "should fail fast if it can't determine RAILS ROOT" do
+ MultiRails::RailsAppHelper.expects(:find_rails_root_dir).returns(nil)
+ lambda { MultiRails::RailsAppHelper.set_rails_root }.should.raise
+ end
+
+end
+
+describe "writing rails gem version file" do
+ setup { Object.const_set("RAILS_ROOT", "/src/rails_app")}
+ teardown { Object.send(:remove_const, "RAILS_ROOT")}
+
+ it "should write to the correct file" do
+ File.expects(:open).with("#{RAILS_ROOT}/config/rails_version.rb", 'w')
+ MultiRails::RailsAppHelper.write_rails_gem_version_file('1.2.5')
+ end
+
+end
+
+describe "init for rails app" do
+ it "should set rails root, write rails gem version file, and rename vendor rails" do
+ version = "1.2.6"
+ MultiRails::RailsAppHelper.expects(:set_rails_root)
+ MultiRails::RailsAppHelper.expects(:write_rails_gem_version_file).with(version)
+ MultiRails::RailsAppHelper.expects(:rename_vendor_rails_if_necessary)
+ MultiRails::RailsAppHelper.init_for_rails_app(version)
+ end
+end
+
+describe "renaming vendor/rails if it exists" do
+ setup { Object.const_set("RAILS_ROOT", "/src/rails_app")}
+ teardown { Object.send(:remove_const, "RAILS_ROOT")}
+
+ it "should rename with .OFF extension so that gem version is picked up during test run" do
+ vendor_rails = "#{RAILS_ROOT}/vendor/rails"
+ File.stubs(:directory?).returns(true)
+ File.expects(:rename).with(vendor_rails, "#{vendor_rails}.off")
+ MultiRails::RailsAppHelper.rename_vendor_rails_if_necessary
+ end
+
+ it "should do nothing if there is no vendor/rails" do
+ File.expects(:directory?).returns(false)
+ File.expects(:rename).never
+ MultiRails::RailsAppHelper.rename_vendor_rails_if_necessary
+ end
+end
+
+describe "adding require hook to top of environment.rb using mocks" do
+ setup { Object.const_set("RAILS_ROOT", "/src/rails_app")}
+ teardown { Object.send(:remove_const, "RAILS_ROOT")}
+
+ it "should raise if it can't find environment.rb" do
+ e = lambda { MultiRails::RailsAppHelper.add_require_line_to_environment_file }.should.raise(MultiRailsError)
+ end
+
+ it "should not do anything if the line is already in the file" do
+ File.stubs(:exist?).returns(true)
+ File.expects(:open).never
+ MultiRails::RailsAppHelper.expects(:first_environment_line).returns(MultiRails::RailsAppHelper::REQUIRE_LINE)
+ MultiRails::RailsAppHelper.add_require_line_to_environment_file
+ end
+
+end
+
+describe "adding require hook to top of environment.rb (without using mocks)" do
+
+ setup do
+ Object.const_set("RAILS_ROOT", "/src/rails_app")
+ @env_content = <<-EOL
+# Be sure to restart your web server when you modify this file.
+
+# Uncomment below to force Rails into production mode when
+# you don't control web/app server and can't set it the proper way
+# ENV['RAILS_ENV'] ||= 'production'
+
+# Specifies gem version of Rails to use when vendor/rails is not present
+RAILS_GEM_VERSION = '1.2.5' unless defined? RAILS_GEM_VERSION
+EOL
+ @file = Tempfile.new('sample_environment')
+ @file << @env_content
+ @file.close
+ end
+
+ teardown do
+ Object.send(:remove_const, "RAILS_ROOT")
+ end
+
+ it "should add the require line" do
+ MultiRails::RailsAppHelper.stubs(:environment_file).returns(@file.path)
+ MultiRails::RailsAppHelper.add_require_line_to_environment_file
+ @file.open.rewind
+ lines = @file.readlines
+ lines[0].to_s.should == (MultiRails::RailsAppHelper::REQUIRE_LINE + "\n")
+ lines[1..-1].to_s.should == @env_content
+ end
+
+end

0 comments on commit ab771e5

Please sign in to comment.