Upgraded to Rails 2.3.4 (#3597)

* Ran the Rails upgrade
* Upgraded to Rails Engines 2.3.2
* Added a plugin to let Engines override application views.
* Converted tests to use the new classes:
** ActionController::TestCase for functional
** ActiveSupport::TestCase for units
* Converted ActiveRecord::Error message to a string.
* ActiveRecord grouping returns an ordered hash which doesn't have #sort!
* Updated the I18n storage_units format.
* Added some default initializers from a fresh rails app
* Changed the order of check_box_tags and hidden_field_tags.  The hidden tag
  needs to appear first in Rails 2.3, otherwise it will override any value in
  the check_box_tag.
* Removed the custom handler for when the cookie store is tampered with.
  Rails 2.3 removed the TamperedWithCookie exception and instead Rails will not
  load the data from it when it's been tampered with (e.g. no user login).
* Fixed mail layouts, 2.3 has problems with implicit multipart emails that
  use layouts.  Also removed some custom Redmine mailer code.
* Fixed a bug that occurred in tests where the "required" span tag would be
  added to the :field_status translation.  This resulted in an email string of:

    <li>Status<span class="required"> *</span><span class="required"> *</span>

  Instead of:

    <li>Status: New</li>

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2887 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Eric Davis
2009-09-13 17:14:35 +00:00
parent fb349dc4ab
commit 7b0cb6aba8
263 changed files with 1636 additions and 440 deletions
@@ -0,0 +1,5 @@
class AppAndPluginController < ApplicationController
def an_action
render_class_and_action 'from app'
end
end
@@ -0,0 +1,5 @@
class Namespace::AppAndPluginController < ApplicationController
def an_action
render_class_and_action 'from app'
end
end
@@ -0,0 +1,5 @@
module MailHelper
def do_something_helpful(var)
var.to_s.reverse
end
end
@@ -0,0 +1,3 @@
class AppAndPluginModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
+26
View File
@@ -0,0 +1,26 @@
class NotifyMail < ActionMailer::Base
helper :mail
def signup(txt)
body(:name => txt)
end
def multipart
recipients 'some_address@email.com'
subject 'multi part email'
from "another_user@email.com"
content_type 'multipart/alternative'
part :content_type => "text/html", :body => render_message("multipart_html", {})
part "text/plain" do |p|
p.body = render_message("multipart_plain", {})
end
end
def implicit_multipart
recipients 'some_address@email.com'
subject 'multi part email'
from "another_user@email.com"
end
end
+3
View File
@@ -0,0 +1,3 @@
class Thing
def self.from_app; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from app)
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from app)
@@ -0,0 +1 @@
the implicit html part of the email <%= do_something_helpful("semaj") %>
@@ -0,0 +1 @@
the implicit plaintext part of the email
@@ -0,0 +1 @@
the html part of the email <%= do_something_helpful("semaj") %>
@@ -0,0 +1 @@
the plaintext part of the email
@@ -0,0 +1,5 @@
Signup template from application
Here's a local variable set in the Mail object: <%= @name %>.
And here's a method called in a mail helper: <%= do_something_helpful(@name) %>
@@ -0,0 +1 @@
<%= @note %> (from application)
@@ -0,0 +1 @@
plugin mail template loaded from application
@@ -0,0 +1,51 @@
# Tests in this file ensure that:
#
# * plugin controller actions are found
# * actions defined in application controllers take precedence over those in plugins
# * actions in controllers in subsequently loaded plugins take precendence over those in previously loaded plugins
# * this works for actions in namespaced controllers accordingly
require File.dirname(__FILE__) + '/../test_helper'
class ControllerLoadingTest < ActionController::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
# plugin controller actions should be found
def test_WITH_an_action_defined_only_in_a_plugin_IT_should_use_this_action
get_action_on_controller :an_action, :alpha_plugin
assert_response_body 'rendered in AlphaPluginController#an_action'
end
def test_WITH_an_action_defined_only_in_a_namespaced_plugin_controller_IT_should_use_this_action
get_action_on_controller :an_action, :alpha_plugin, :namespace
assert_response_body 'rendered in Namespace::AlphaPluginController#an_action'
end
# app takes precedence over plugins
def test_WITH_an_action_defined_in_both_app_and_plugin_IT_should_use_the_one_in_app
get_action_on_controller :an_action, :app_and_plugin
assert_response_body 'rendered in AppAndPluginController#an_action (from app)'
end
def test_WITH_an_action_defined_in_namespaced_controllers_in_both_app_and_plugin_IT_should_use_the_one_in_app
get_action_on_controller :an_action, :app_and_plugin, :namespace
assert_response_body 'rendered in Namespace::AppAndPluginController#an_action (from app)'
end
# subsequently loaded plugins take precendence over previously loaded plugins
def test_WITH_an_action_defined_in_two_plugin_controllers_IT_should_use_the_latter_of_both
get_action_on_controller :an_action, :shared_plugin
assert_response_body 'rendered in SharedPluginController#an_action (from beta_plugin)'
end
def test_WITH_an_action_defined_in_two_namespaced_plugin_controllers_IT_should_use_the_latter_of_both
get_action_on_controller :an_action, :shared_plugin, :namespace
assert_response_body 'rendered in Namespace::SharedPluginController#an_action (from beta_plugin)'
end
end
@@ -0,0 +1,29 @@
require File.dirname(__FILE__) + '/../test_helper'
class ExceptionNotificationCompatibilityTest < ActionController::TestCase
ExceptionNotifier.exception_recipients = %w(joe@schmoe.com bill@schmoe.com)
class SimpleController < ApplicationController
include ExceptionNotifiable
local_addresses.clear
consider_all_requests_local = false
def index
begin
raise "Fail!"
rescue Exception => e
rescue_action_in_public(e)
end
end
end
def setup
@controller = SimpleController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
def test_should_work
assert_nothing_raised do
get :index
end
end
end
@@ -0,0 +1,26 @@
# Tests in this file ensure that:
#
# * translations in the application take precedence over those in plugins
# * translations in subsequently loaded plugins take precendence over those in previously loaded plugins
require File.dirname(__FILE__) + '/../test_helper'
class LocaleLoadingTest < ActionController::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
# app takes precedence over plugins
def test_WITH_a_translation_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
assert_equal I18n.t('hello'), 'Hello world'
end
# subsequently loaded plugins take precendence over previously loaded plugins
def test_WITH_a_translation_defined_in_two_plugins_IT_should_find_the_latter_of_both
assert_equal I18n.t('plugin'), 'beta'
end
end
+29
View File
@@ -0,0 +1,29 @@
# Tests in this file ensure that:
#
# * Routes from plugins can be routed to
# * Named routes can be defined within a plugin
require File.dirname(__FILE__) + '/../test_helper'
class RoutesTest < ActionController::TestCase
tests TestRoutingController
def test_WITH_a_route_defined_in_a_plugin_IT_should_route_it
path = '/routes/an_action'
opts = {:controller => 'test_routing', :action => 'an_action'}
assert_routing path, opts
assert_recognizes opts, path # not sure what exactly the difference is, but it won't hurt either
end
def test_WITH_a_route_for_a_namespaced_controller_defined_in_a_plugin_IT_should_route_it
path = 'somespace/routes/an_action'
opts = {:controller => 'namespace/test_routing', :action => 'an_action'}
assert_routing path, opts
assert_recognizes opts, path
end
def test_should_properly_generate_named_routes
get :test_named_routes_from_plugin
assert_response_body '/somespace/routes'
end
end
@@ -0,0 +1,37 @@
require File.dirname(__FILE__) + '/../test_helper'
class ViewHelpersTest < ActionController::TestCase
tests AssetsController
def setup
get :index
end
def test_plugin_javascript_helpers
base_selector = "script[type='text/javascript']"
js_dir = "/plugin_assets/test_assets/javascripts"
assert_select "#{base_selector}[src='#{js_dir}/file.1.js']"
assert_select "#{base_selector}[src='#{js_dir}/file2.js']"
end
def test_plugin_stylesheet_helpers
base_selector = "link[media='screen'][rel='stylesheet'][type='text/css']"
css_dir = "/plugin_assets/test_assets/stylesheets"
assert_select "#{base_selector}[href='#{css_dir}/file.1.css']"
assert_select "#{base_selector}[href='#{css_dir}/file2.css']"
end
def test_plugin_image_helpers
assert_select "img[src='/plugin_assets/test_assets/images/image.png'][alt='Image']"
end
def test_plugin_layouts
get :index
assert_select "div[id='assets_layout']"
end
def test_plugin_image_submit_helpers
assert_select "input[src='/plugin_assets/test_assets/images/image.png'][type='image']"
end
end
@@ -0,0 +1,60 @@
# Tests in this file ensure that:
#
# * plugin views are found
# * views in the application take precedence over those in plugins
# * views in subsequently loaded plugins take precendence over those in previously loaded plugins
# * this works for namespaced views accordingly
require File.dirname(__FILE__) + '/../test_helper'
class ViewLoadingTest < ActionController::TestCase
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end
# plugin views should be found
def test_WITH_a_view_defined_only_in_a_plugin_IT_should_find_the_view
get_action_on_controller :a_view, :alpha_plugin
assert_response_body 'alpha_plugin/a_view'
end
def test_WITH_a_namespaced_view_defined_only_in_a_plugin_IT_should_find_the_view
get_action_on_controller :a_view, :alpha_plugin, :namespace
assert_response_body 'namespace/alpha_plugin/a_view'
end
# app takes precedence over plugins
def test_WITH_a_view_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
get_action_on_controller :a_view, :app_and_plugin
assert_response_body 'app_and_plugin/a_view (from app)'
end
def test_WITH_a_namespaced_view_defined_in_both_app_and_plugin_IT_should_find_the_one_in_app
get_action_on_controller :a_view, :app_and_plugin, :namespace
assert_response_body 'namespace/app_and_plugin/a_view (from app)'
end
# subsequently loaded plugins take precendence over previously loaded plugins
def test_WITH_a_view_defined_in_two_plugins_IT_should_find_the_latter_of_both
get_action_on_controller :a_view, :shared_plugin
assert_response_body 'shared_plugin/a_view (from beta_plugin)'
end
def test_WITH_a_namespaced_view_defined_in_two_plugins_IT_should_find_the_latter_of_both
get_action_on_controller :a_view, :shared_plugin, :namespace
assert_response_body 'namespace/shared_plugin/a_view (from beta_plugin)'
end
# layouts loaded from plugins
def test_should_be_able_to_load_a_layout_from_a_plugin
get_action_on_controller :action_with_layout, :alpha_plugin
assert_response_body 'rendered in AlphaPluginController#action_with_layout (with plugin layout)'
end
end
@@ -0,0 +1,3 @@
class AppAndPluginLibModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
+42
View File
@@ -0,0 +1,42 @@
module TestHelper
def self.report_location(path)
[RAILS_ROOT + '/', 'vendor/plugins/'].each { |part| path.sub! part, ''}
path = path.split('/')
location, subject = path.first, path.last
if subject.sub! '.rb', ''
subject = subject.classify
else
subject.sub! '.html.erb', ''
end
"#{subject} (from #{location})"
end
def self.view_path_for path
[RAILS_ROOT + '/', 'vendor/plugins/', '.html.erb'].each { |part| path.sub! part, ''}
parts = path.split('/')
parts[(parts.index('views')+1)..-1].join('/')
end
end
class Test::Unit::TestCase
# Add more helper methods to be used by all tests here...
def get_action_on_controller(*args)
action = args.shift
with_controller *args
get action
end
def with_controller(controller, namespace = nil)
classname = controller.to_s.classify + 'Controller'
classname = namespace.to_s.classify + '::' + classname unless namespace.nil?
@controller = classname.constantize.new
end
def assert_response_body(expected)
assert_equal expected, @response.body
end
end
# Because we're testing this behaviour, we actually want these features on!
Engines.disable_application_view_loading = false
Engines.disable_application_code_loading = false
+7
View File
@@ -0,0 +1,7 @@
module RenderInformation
def render_class_and_action(note = nil, options={})
text = "rendered in #{self.class.name}##{params[:action]}"
text += " (#{note})" unless note.nil?
render options.update(:text => text)
end
end
@@ -0,0 +1,8 @@
class AlphaPluginController < ApplicationController
def an_action
render_class_and_action
end
def action_with_layout
render_class_and_action(nil, :layout => "plugin_layout")
end
end
@@ -0,0 +1,5 @@
class AppAndPluginController < ApplicationController
def an_action
render_class_and_action 'from alpha_plugin'
end
end
@@ -0,0 +1,5 @@
class Namespace::AlphaPluginController < ApplicationController
def an_action
render_class_and_action
end
end
@@ -0,0 +1,5 @@
class Namespace::AppAndPluginController < ApplicationController
def an_action
render_class_and_action 'from alpha_plugin'
end
end
@@ -0,0 +1,5 @@
class Namespace::SharedPluginController < ApplicationController
def an_action
render_class_and_action 'from alpha_plugin'
end
end
@@ -0,0 +1,5 @@
class SharedEngineController < ApplicationController
def an_action
render_class_and_action 'from alpha_engine'
end
end
@@ -0,0 +1,3 @@
class AlphaPluginModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1,7 @@
class AppAndPluginModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
def defined_only_in_alpha_plugin_version
# should not be defined as the model in app/models takes precedence
end
end
@@ -0,0 +1,3 @@
class SharedPluginModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %>
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from a_view)
@@ -0,0 +1 @@
<%= yield %> (with plugin layout)
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %>
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %>
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from alpha_plugin)
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from alpha_plugin)
@@ -0,0 +1,3 @@
class AlphaPluginLibModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1,7 @@
class AppAndPluginLibModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
def defined_only_in_alpha_plugin_version
# should not be defined
end
end
@@ -0,0 +1,3 @@
en:
hello: "Hello from alfa"
plugin: "alfa"
@@ -0,0 +1,5 @@
class AppAndPluginController < ApplicationController
def an_action
render_class_and_action 'from beta_plugin'
end
end
@@ -0,0 +1,5 @@
class Namespace::SharedPluginController < ApplicationController
def an_action
render_class_and_action 'from beta_plugin'
end
end
@@ -0,0 +1,5 @@
class SharedPluginController < ApplicationController
def an_action
render_class_and_action 'from beta_plugin'
end
end
@@ -0,0 +1,3 @@
class SharedPluginModel < ActiveRecord::Base
def self.report_location; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from beta_plugin)
@@ -0,0 +1 @@
<%= TestHelper.view_path_for __FILE__ %> (from beta_plugin)
@@ -0,0 +1 @@
# just here so that Rails recognizes this as a plugin
@@ -0,0 +1,3 @@
en:
hello: "Hello from beta"
plugin: "beta"
@@ -0,0 +1,2 @@
class AssetsController < ApplicationController
end
@@ -0,0 +1,4 @@
<%= image_tag 'image.png', :plugin => 'test_assets' %>
<%= javascript_include_tag 'file.1.js', 'file2', :plugin => "test_assets" %>
<%= stylesheet_link_tag 'file.1.css', 'file2', :plugin => "test_assets" %>
<%= image_submit_tag 'image.png', :plugin => "test_assets" %>
@@ -0,0 +1,3 @@
<div id="assets_layout">
<%= yield %>
</div>
@@ -0,0 +1,3 @@
class Thing
def self.from_plugin; TestHelper::report_location(__FILE__); end
end
@@ -0,0 +1 @@
# just here so that Rails recognizes this as a plugin
@@ -0,0 +1,11 @@
class CreateTests < ActiveRecord::Migration
def self.up
create_table 'tests' do |t|
t.column 'name', :string
end
end
def self.down
drop_table 'tests'
end
end
@@ -0,0 +1,11 @@
class CreateOthers < ActiveRecord::Migration
def self.up
create_table 'others' do |t|
t.column 'name', :string
end
end
def self.down
drop_table 'others'
end
end
@@ -0,0 +1,11 @@
class CreateExtras < ActiveRecord::Migration
def self.up
create_table 'extras' do |t|
t.column 'name', :string
end
end
def self.down
drop_table 'extras'
end
end
@@ -0,0 +1,26 @@
class PluginMail < ActionMailer::Base
def mail_from_plugin(note=nil)
body(:note => note)
end
def mail_from_plugin_with_application_template(note=nil)
body(:note => note)
end
def multipart_from_plugin
content_type 'multipart/alternative'
part :content_type => "text/html", :body => render_message("multipart_from_plugin_html", {})
part "text/plain" do |p|
p.body = render_message("multipart_from_plugin_plain", {})
end
end
def multipart_from_plugin_with_application_template
content_type 'multipart/alternative'
part :content_type => "text/html", :body => render_message("multipart_from_plugin_with_application_template_html", {})
part "text/plain" do |p|
p.body = render_message("multipart_from_plugin_with_application_template_plain", {})
end
end
end
@@ -0,0 +1,5 @@
class Namespace::TestRoutingController < ApplicationController
def routed_action
render_class_and_action
end
end
@@ -0,0 +1,9 @@
class TestRoutingController < ApplicationController
def routed_action
render_class_and_action
end
def test_named_routes_from_plugin
render :text => plugin_route_path(:action => "index")
end
end
@@ -0,0 +1,4 @@
ActionController::Routing::Routes.draw do |map|
map.connect 'routes/:action', :controller => "test_routing"
map.plugin_route 'somespace/routes/:action', :controller => "namespace/test_routing"
end
@@ -0,0 +1 @@
Fixtures are only copied from plugins with an +app+ directory, but git needs this directory to be non-empty
@@ -0,0 +1,13 @@
require File.expand_path(File.join(File.dirname(__FILE__), *%w[.. .. .. .. .. test test_helper]))
class OverrideTest < ActiveSupport::TestCase
def test_overrides_from_the_application_should_work
flunk "this test should be overridden by the app"
end
def test_tests_within_the_plugin_should_still_run
assert true, "non-overridden plugin tests should still run"
end
end
Engines::Testing.override_tests_from_app
+54
View File
@@ -0,0 +1,54 @@
require File.dirname(__FILE__) + '/../test_helper'
class ActionMailerWithinApplicationTest < Test::Unit::TestCase
def test_normal_implicit_template
m = NotifyMail.create_signup("hello")
assert m.body =~ /^Signup template from application/
end
def test_action_mailer_can_get_helper
m = NotifyMail.create_signup('James')
assert m.body =~ /James/
assert m.body =~ /semaJ/ # from the helper
end
def test_multipart_mails_with_explicit_templates
m = NotifyMail.create_multipart
assert_equal 2, m.parts.length
assert_equal 'the html part of the email james', m.parts[0].body
assert_equal 'the plaintext part of the email', m.parts[1].body
end
def test_multipart_mails_with_implicit_templates
m = NotifyMail.create_implicit_multipart
assert_equal 2, m.parts.length
assert_equal 'the implicit plaintext part of the email', m.parts[0].body
assert_equal 'the implicit html part of the email james', m.parts[1].body
end
end
class ActionMailerWithinPluginsTest < Test::Unit::TestCase
def test_should_be_able_to_create_mails_from_plugin
m = PluginMail.create_mail_from_plugin("from_plugin")
assert_equal "from_plugin", m.body
end
def test_should_be_able_to_overload_views_within_the_application
m = PluginMail.create_mail_from_plugin_with_application_template("from_plugin")
assert_equal "from_plugin (from application)", m.body
end
def test_should_be_able_to_create_a_multipart_mail_from_within_plugin
m = PluginMail.create_multipart_from_plugin
assert_equal 2, m.parts.length
assert_equal 'html template', m.parts[0].body
assert_equal 'plain template', m.parts[1].body
end
def test_plugin_mailer_template_overriding
m = PluginMail.create_multipart_from_plugin_with_application_template
assert_equal 'plugin mail template loaded from application', m.parts[1].body
end
end
@@ -0,0 +1,41 @@
require File.dirname(__FILE__) + '/../test_helper'
class ArbitraryCodeMixingTest < Test::Unit::TestCase
def setup
Engines.code_mixing_file_types = %w(controller helper)
end
def test_should_allow_setting_of_different_code_mixing_file_types
assert_nothing_raised {
Engines.mix_code_from :things
}
end
def test_should_add_new_types_to_existing_code_mixing_file_types
Engines.mix_code_from :things
assert_equal ["controller", "helper", "thing"], Engines.code_mixing_file_types
Engines.mix_code_from :other
assert_equal ["controller", "helper", "thing", "other"], Engines.code_mixing_file_types
end
def test_should_allow_setting_of_multiple_types_at_once
Engines.mix_code_from :things, :other
assert_equal ["controller", "helper", "thing", "other"], Engines.code_mixing_file_types
end
def test_should_singularize_elements_to_be_mixed
# this is the only test using mocha, so let's try to work around it
# also, this seems to be already tested with the :things in the tests above
# arg = stub(:to_s => stub(:singularize => "element"))
Engines.mix_code_from :elements
assert Engines.code_mixing_file_types.include?("element")
end
# TODO doesn't seem to work as expected?
# def test_should_successfully_mix_custom_types
# Engines.mix_code_from :things
# assert_equal 'Thing (from app)', Thing.from_app
# assert_equal 'Thing (from test_code_mixing)', Thing.from_plugin
# end
end
+52
View File
@@ -0,0 +1,52 @@
require File.dirname(__FILE__) + '/../test_helper'
class AssetsTest < Test::Unit::TestCase
def setup
Engines::Assets.mirror_files_for Engines.plugins[:test_assets]
end
def teardown
FileUtils.rm_r(Engines.public_directory) if File.exist?(Engines.public_directory)
end
def test_engines_has_created_base_public_file
assert File.exist?(Engines.public_directory)
end
def test_engines_has_created_README_in_public_directory
assert File.exist?(File.join(Engines.public_directory, 'README'))
end
def test_public_files_have_been_copied_from_test_assets_plugin
assert File.exist?(File.join(Engines.public_directory, 'test_assets'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'file.txt'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'subfolder'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets', 'subfolder', 'file_in_subfolder.txt'))
end
def test_engines_has_not_created_duplicated_file_structure
assert !File.exists?(File.join(Engines.public_directory, "test_assets", RAILS_ROOT))
end
def test_public_files_have_been_copied_from_test_assets_with_assets_dir_plugin
Engines::Assets.mirror_files_for Engines.plugins[:test_assets_with_assets_directory]
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'file.txt'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'subfolder'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_assets_directory', 'subfolder', 'file_in_subfolder.txt'))
end
def test_public_files_have_been_copied_from_test_assets_with_no_subdirectory_plugin
Engines::Assets.mirror_files_for Engines.plugins[:test_assets_with_no_subdirectory]
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_no_subdirectory'))
assert File.exist?(File.join(Engines.public_directory, 'test_assets_with_no_subdirectory', 'file.txt'))
end
def test_public_files_have_NOT_been_copied_from_plugins_without_public_or_asset_directories
Engines::Assets.mirror_files_for Engines.plugins[:alpha_plugin]
assert !File.exist?(File.join(Engines.public_directory, 'alpha_plugin'))
end
end
@@ -0,0 +1,8 @@
require File.dirname(__FILE__) + '/../test_helper'
class BackwardsCompatibilityTest < Test::Unit::TestCase
def test_rails_module_plugin_method_should_delegate_to_engines_plugins
assert_nothing_raised { Rails.plugins }
assert_equal Engines.plugins, Rails.plugins
end
end
+58
View File
@@ -0,0 +1,58 @@
# Tests in this file ensure that:
#
# * the application /app/[controllers|helpers|models] and /lib
# paths preceed the corresponding plugin paths
# * the plugin paths are added to $LOAD_PATH in the order in which plugins are
# loaded
require File.dirname(__FILE__) + '/../test_helper'
class LoadPathTest < Test::Unit::TestCase
def setup
@load_path = expand_paths($LOAD_PATH)
end
# Not sure if these test actually make sense as this now essentially tests
# Rails core functionality. On the other hand Engines relies on this to some
# extend so this will choke if something important changes in Rails.
# the application app/... and lib/ directories should appear
# before any plugin directories
def test_application_app_libs_should_precede_all_plugin_app_libs
types = %w(app/controllers app/helpers app/models lib)
types.each do |t|
app_index = load_path_index(File.join(RAILS_ROOT, t))
assert_not_nil app_index, "#{t} is missing in $LOAD_PATH"
Engines.plugins.each do |plugin|
first_plugin_index = load_path_index(File.join(plugin.directory, t))
assert(app_index < first_plugin_index) unless first_plugin_index.nil?
end
end
end
# the engine directories should appear in the proper order based on
# the order they were started
def test_plugin_dirs_should_appear_in_reverse_plugin_loading_order
app_paths = %w(app/controllers/ app app/models app/helpers lib)
app_paths.map { |p| File.join(RAILS_ROOT, p)}
plugin_paths = Engines.plugins.reverse.collect { |plugin| plugin.load_paths.reverse }.flatten
expected_paths = expand_paths(app_paths + plugin_paths)
# only look at those paths that are also present in expected_paths so
# the only difference would be in the order of the paths
actual_paths = @load_path & expected_paths
assert_equal expected_paths, actual_paths
end
protected
def expand_paths(paths)
paths.collect { |p| File.expand_path(p) }
end
def load_path_index(dir)
@load_path.index(File.expand_path(dir))
end
end
+63
View File
@@ -0,0 +1,63 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'rails_generator'
require 'rails_generator/scripts/generate'
class MigrationsTest < Test::Unit::TestCase
@@migration_dir = "#{RAILS_ROOT}/db/migrate"
def setup
ActiveRecord::Migration.verbose = false
Engines.plugins[:test_migration].migrate(0)
end
def teardown
FileUtils.rm_r(@@migration_dir) if File.exist?(@@migration_dir)
end
def test_engine_migrations_can_run_down
assert !table_exists?('tests'), ActiveRecord::Base.connection.tables.inspect
assert !table_exists?('others'), ActiveRecord::Base.connection.tables.inspect
assert !table_exists?('extras'), ActiveRecord::Base.connection.tables.inspect
end
def test_engine_migrations_can_run_up
Engines.plugins[:test_migration].migrate(3)
assert table_exists?('tests')
assert table_exists?('others')
assert table_exists?('extras')
end
def test_engine_migrations_can_upgrade_incrementally
Engines.plugins[:test_migration].migrate(1)
assert table_exists?('tests')
assert !table_exists?('others')
assert !table_exists?('extras')
assert_equal 1, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
Engines.plugins[:test_migration].migrate(2)
assert table_exists?('others')
assert_equal 2, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
Engines.plugins[:test_migration].migrate(3)
assert table_exists?('extras')
assert_equal 3, Engines::Plugin::Migrator.current_version(Engines.plugins[:test_migration])
end
def test_generator_creates_plugin_migration_file
Rails::Generator::Scripts::Generate.new.run(['plugin_migration', 'test_migration'], :quiet => true)
assert migration_file, "migration file is missing"
end
private
def table_exists?(table)
ActiveRecord::Base.connection.tables.include?(table)
end
def migration_file
Dir["#{@@migration_dir}/*test_migration_to_version_3.rb"][0]
end
end
+37
View File
@@ -0,0 +1,37 @@
require File.dirname(__FILE__) + '/../test_helper'
class ModelAndLibTest < Test::Unit::TestCase
def test_WITH_a_model_defined_only_in_a_plugin_IT_should_load_the_model
assert_equal 'AlphaPluginModel (from alpha_plugin)', AlphaPluginModel.report_location
end
def test_WITH_a_model_defined_only_in_a_plugin_lib_dir_IT_should_load_the_model
assert_equal 'AlphaPluginLibModel (from alpha_plugin)', AlphaPluginLibModel.report_location
end
# app takes precedence over plugins
def test_WITH_a_model_defined_in_both_app_and_plugin_IT_should_load_the_one_in_app
assert_equal 'AppAndPluginModel (from app)', AppAndPluginModel.report_location
assert_raises(NoMethodError) { AppAndPluginLibModel.defined_only_in_alpha_engine_version }
end
def test_WITH_a_model_defined_in_both_app_and_plugin_lib_dirs_IT_should_load_the_one_in_app
assert_equal 'AppAndPluginLibModel (from lib)', AppAndPluginLibModel.report_location
assert_raises(NoMethodError) { AppAndPluginLibModel.defined_only_in_alpha_engine_version }
end
# subsequently loaded plugins take precendence over previously loaded plugins
# TODO
#
# this does work when we rely on $LOAD_PATH while it won't work when we use
# Dependency constant autoloading. This somewhat confusing difference has
# been there since at least Rails 1.2.x. See http://www.ruby-forum.com/topic/134529
def test_WITH_a_model_defined_in_two_plugins_IT_should_load_the_latter_of_both
require 'shared_plugin_model'
assert_equal SharedPluginModel.report_location, 'SharedPluginModel (from beta_plugin)'
end
end
+11
View File
@@ -0,0 +1,11 @@
require File.dirname(__FILE__) + '/../test_helper'
class PluginsTest < Test::Unit::TestCase
def test_should_allow_access_to_plugins_by_strings_or_symbols
p = Engines.plugins["alpha_plugin"]
q = Engines.plugins[:alpha_plugin]
assert_kind_of Engines::Plugin, p
assert_equal p, q
end
end
@@ -0,0 +1,7 @@
require File.join(File.dirname(__FILE__), *%w[.. .. test_helper])
class OverrideTest < ActiveSupport::TestCase
def test_overrides_from_the_application_should_work
assert true, "overriding plugin tests from the application should work"
end
end
+19
View File
@@ -0,0 +1,19 @@
require File.dirname(__FILE__) + '/../test_helper'
class TestingTest < Test::Unit::TestCase
def setup
Engines::Testing.set_fixture_path
@filename = File.join(Engines::Testing.temporary_fixtures_directory, 'testing_fixtures.yml')
File.delete(@filename) if File.exists?(@filename)
end
def teardown
File.delete(@filename) if File.exists?(@filename)
end
def test_should_copy_fixtures_files_to_tmp_directory
assert !File.exists?(@filename)
Engines::Testing.setup_plugin_fixtures
assert File.exists?(@filename)
end
end