aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-10-10 17:15:11 +0100
committerPratik Naik <pratiknaik@gmail.com>2009-10-10 17:15:11 +0100
commit66ee2654ff243f03595a402fa15e1eea1b5b45be (patch)
tree3f1055e03082f0c767719e8cba5155e4207779e0
parentdd2779e1b83b4d867d47dd286ec0c919f5df12a9 (diff)
parentb9ce8216fa849a47ad0b0f99fa510e226a23c12e (diff)
downloadrails-66ee2654ff243f03595a402fa15e1eea1b5b45be.tar.gz
rails-66ee2654ff243f03595a402fa15e1eea1b5b45be.tar.bz2
rails-66ee2654ff243f03595a402fa15e1eea1b5b45be.zip
Merge commit 'mainstream/master'
-rw-r--r--.gitignore1
-rw-r--r--actionmailer/test/fixtures/helpers/example_helper.rb2
-rw-r--r--actionpack/Gemfile1
-rw-r--r--actionpack/Rakefile11
-rw-r--r--actionpack/lib/action_controller/dispatch/dispatcher.rb2
-rw-r--r--actionpack/lib/action_controller/metal/session_management.rb2
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb7
-rw-r--r--actionpack/lib/action_dispatch/middleware/string_coercion.rb29
-rw-r--r--actionpack/lib/action_view.rb6
-rw-r--r--actionpack/lib/action_view/base.rb13
-rw-r--r--actionpack/lib/action_view/erb/util.rb12
-rw-r--r--actionpack/lib/action_view/helpers.rb2
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/raw_output_helper.rb9
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb12
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb10
-rw-r--r--actionpack/lib/action_view/paths.rb7
-rw-r--r--actionpack/lib/action_view/render/partials.rb7
-rw-r--r--actionpack/lib/action_view/render/rendering.rb22
-rw-r--r--actionpack/lib/action_view/safe_buffer.rb28
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb28
-rw-r--r--actionpack/lib/action_view/test_case.rb2
-rw-r--r--actionpack/test/abstract_unit.rb94
-rw-r--r--actionpack/test/activerecord/active_record_store_test.rb1
-rw-r--r--actionpack/test/controller/caching_test.rb22
-rw-r--r--actionpack/test/controller/integration_test.rb5
-rw-r--r--actionpack/test/controller/mime_responds_test.rb150
-rw-r--r--actionpack/test/controller/new_base/base_test.rb (renamed from actionpack/test/new_base/base_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/content_negotiation_test.rb (renamed from actionpack/test/new_base/content_negotiation_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/content_type_test.rb (renamed from actionpack/test/new_base/content_type_test.rb)6
-rw-r--r--actionpack/test/controller/new_base/etag_test.rb (renamed from actionpack/test/new_base/etag_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/metal_test.rb (renamed from actionpack/test/new_base/metal_test.rb)0
-rw-r--r--actionpack/test/controller/new_base/middleware_test.rb (renamed from actionpack/test/new_base/middleware_test.rb)0
-rw-r--r--actionpack/test/controller/new_base/render_action_test.rb (renamed from actionpack/test/new_base/render_action_test.rb)12
-rw-r--r--actionpack/test/controller/new_base/render_file_test.rb (renamed from actionpack/test/new_base/render_file_test.rb)71
-rw-r--r--actionpack/test/controller/new_base/render_implicit_action_test.rb (renamed from actionpack/test/new_base/render_implicit_action_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/render_layout_test.rb (renamed from actionpack/test/new_base/render_layout_test.rb)6
-rw-r--r--actionpack/test/controller/new_base/render_partial_test.rb (renamed from actionpack/test/new_base/render_partial_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/render_rjs_test.rb (renamed from actionpack/test/new_base/render_rjs_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/render_template_test.rb (renamed from actionpack/test/new_base/render_template_test.rb)6
-rw-r--r--actionpack/test/controller/new_base/render_test.rb (renamed from actionpack/test/new_base/render_test.rb)6
-rw-r--r--actionpack/test/controller/new_base/render_text_test.rb (renamed from actionpack/test/new_base/render_text_test.rb)2
-rw-r--r--actionpack/test/controller/new_base/render_xml_test.rb (renamed from actionpack/test/new_base/render_xml_test.rb)0
-rw-r--r--actionpack/test/controller/output_escaping_test.rb19
-rw-r--r--actionpack/test/controller/render_test.rb2
-rw-r--r--actionpack/test/controller/rescue_test.rb1
-rw-r--r--actionpack/test/controller/routing_test.rb62
-rw-r--r--actionpack/test/controller/verification_test.rb17
-rw-r--r--actionpack/test/controller/webservice_test.rb1
-rw-r--r--actionpack/test/dispatch/request/json_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/multipart_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/query_string_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/request/xml_params_parsing_test.rb1
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb1
-rw-r--r--actionpack/test/dispatch/session/mem_cache_store_test.rb1
-rw-r--r--actionpack/test/dispatch/string_coercion_test.rb40
-rw-r--r--actionpack/test/lib/controller/fake_controllers.rb31
-rw-r--r--actionpack/test/lib/controller/fake_models.rb96
-rw-r--r--actionpack/test/template/ajax_test.rb (renamed from actionpack/test/javascript/ajax_test.rb)15
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb12
-rw-r--r--actionpack/test/template/erb_util_test.rb12
-rw-r--r--actionpack/test/template/form_helper_test.rb102
-rw-r--r--actionpack/test/template/html-scanner/cdata_node_test.rb (renamed from actionpack/test/html-scanner/cdata_node_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/document_test.rb (renamed from actionpack/test/html-scanner/document_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/node_test.rb (renamed from actionpack/test/html-scanner/node_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/sanitizer_test.rb (renamed from actionpack/test/html-scanner/sanitizer_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/tag_node_test.rb (renamed from actionpack/test/html-scanner/tag_node_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/text_node_test.rb (renamed from actionpack/test/html-scanner/text_node_test.rb)0
-rw-r--r--actionpack/test/template/html-scanner/tokenizer_test.rb (renamed from actionpack/test/html-scanner/tokenizer_test.rb)0
-rw-r--r--actionpack/test/template/raw_output_helper_test.rb21
-rw-r--r--actionpack/test/template/record_tag_helper_test.rb3
-rw-r--r--actionpack/test/template/render_test.rb2
-rw-r--r--actionpack/test/template/sanitize_helper_test.rb11
-rw-r--r--actionpack/test/template/tag_helper_test.rb1
-rw-r--r--actionpack/test/template/test_case_test.rb (renamed from actionpack/test/view/test_case_test.rb)3
-rw-r--r--actionpack/test/template/test_test.rb37
-rw-r--r--actionpack/test/template/url_helper_test.rb2
-rw-r--r--actionpack/test/ts_isolated.rb17
-rw-r--r--actionpack/test/view/safe_buffer_test.rb41
-rw-r--r--activemodel/lib/active_model/attribute_methods.rb7
-rw-r--r--activemodel/lib/active_model/lint.rb78
-rw-r--r--activemodel/test/cases/attribute_methods_test.rb46
-rw-r--r--activemodel/test/cases/lint_test.rb40
-rwxr-xr-xactiverecord/lib/active_record/base.rb65
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb83
-rwxr-xr-xactiverecord/test/cases/base_test.rb2
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb66
-rw-r--r--activerecord/test/models/pirate.rb4
-rw-r--r--activeresource/lib/active_resource/base.rb42
-rw-r--r--activeresource/lib/active_resource/exceptions.rb5
-rw-r--r--activeresource/test/cases/base/load_test.rb38
-rw-r--r--activeresource/test/cases/base_test.rb70
-rw-r--r--activeresource/test/cases/observing_test.rb2
-rw-r--r--activeresource/test/connection_test.rb2
-rw-r--r--activesupport/lib/active_support/cache.rb7
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb2
-rw-r--r--activesupport/lib/active_support/cache/strategy/local_cache.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/string.rb3
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb43
-rw-r--r--activesupport/lib/active_support/message_verifier.rb4
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb4
-rw-r--r--activesupport/test/caching_test.rb19
-rw-r--r--activesupport/test/core_ext/string_ext_test.rb86
-rw-r--r--activesupport/test/message_verifier_test.rb6
-rwxr-xr-xci/ci_build.rb1
-rw-r--r--railties/lib/rails/application.rb484
-rwxr-xr-xrailties/lib/rails/commands/ncgi/listener86
-rw-r--r--railties/lib/rails/core.rb6
-rw-r--r--railties/lib/rails/fcgi_handler.rb239
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/index.html.erb2
-rw-r--r--railties/lib/rails/generators/erb/scaffold/templates/show.html.erb2
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb16
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/boot.rb13
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi24
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb10
-rwxr-xr-xrailties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi97
-rw-r--r--railties/lib/rails/initializable.rb99
-rw-r--r--railties/lib/rails/initializer.rb560
-rw-r--r--railties/lib/rails/initializer_old.rb1137
-rw-r--r--railties/lib/rails/tasks/framework.rake5
-rw-r--r--railties/rails.gemspec2
-rw-r--r--railties/test/abstract_unit.rb8
-rw-r--r--railties/test/application/console_test.rb52
-rw-r--r--railties/test/application/generators_test.rb89
-rw-r--r--railties/test/application/initializer_test.rb194
-rw-r--r--railties/test/application/load_test.rb9
-rw-r--r--railties/test/application/plugins_test.rb101
-rw-r--r--railties/test/console_app_test.rb43
-rw-r--r--railties/test/fcgi_dispatcher_test.rb268
-rw-r--r--railties/test/generators/app_generator_test.rb12
-rw-r--r--railties/test/initializable_test.rb68
-rw-r--r--railties/test/initializer/initialize_i18n_test.rb51
-rw-r--r--railties/test/initializer/path_test.rb2
-rw-r--r--railties/test/initializer_test.rb482
-rw-r--r--railties/test/isolation/abstract_unit.rb13
-rw-r--r--railties/test/new_initializer_test.rb165
-rw-r--r--railties/test/plugin_loader_test.rb17
-rw-r--r--railties/test/plugin_locator_test.rb16
-rw-r--r--railties/test/plugin_test.rb15
151 files changed, 2509 insertions, 3821 deletions
diff --git a/.gitignore b/.gitignore
index 1c94c4b0f8..da296e7e11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,5 +30,4 @@ railties/guides/output
actionpack/bin
vendor/gems/
*/vendor/gems/
-bin/
railties/tmp
diff --git a/actionmailer/test/fixtures/helpers/example_helper.rb b/actionmailer/test/fixtures/helpers/example_helper.rb
index d66927aa60..f6a6a49ced 100644
--- a/actionmailer/test/fixtures/helpers/example_helper.rb
+++ b/actionmailer/test/fixtures/helpers/example_helper.rb
@@ -1,5 +1,5 @@
module ExampleHelper
def example_format(text)
- "<em><strong><small>#{text}</small></strong></em>"
+ "<em><strong><small>#{h(text)}</small></strong></em>".html_safe!
end
end
diff --git a/actionpack/Gemfile b/actionpack/Gemfile
index 7d99e0601b..60d24104d2 100644
--- a/actionpack/Gemfile
+++ b/actionpack/Gemfile
@@ -4,6 +4,7 @@ gem "rack", "~> 1.0.0"
gem "rack-test", "~> 0.5.0"
gem "activesupport", "3.0.pre", :vendored_at => rails_root.join("activesupport")
gem "activemodel", "3.0.pre", :vendored_at => rails_root.join("activemodel")
+gem "erubis", "~> 2.6.0"
only :test do
gem "mocha"
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index af39175047..e186037aeb 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -34,22 +34,21 @@ end
desc "Run all unit tests"
task :test => [:test_action_pack, :test_active_record_integration]
-TESTS_GLOB = "test/{abstract,controller,dispatch,new_base,template,html-scanner,view}/**/*_test.rb"
-
Rake::TestTask.new(:test_action_pack) do |t|
t.libs << 'test'
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
- t.test_files = Dir.glob(TESTS_GLOB).sort
+ t.test_files = Dir.glob('test/{abstract,controller,dispatch,template}/**/*_test.rb').sort
t.verbose = true
# t.warning = true
end
-task :isolated_test do
- ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
- Dir.glob(TESTS_GLOB).all? { |file| system(ruby, '-Ilib:test', file) } or raise "Failures"
+namespace :test do
+ Rake::TestTask.new(:isolated) do |t|
+ t.pattern = 'test/ts_isolated.rb'
+ end
end
desc 'ActiveRecord Integration Tests'
diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb
index e04da42637..008fb54715 100644
--- a/actionpack/lib/action_controller/dispatch/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb
@@ -50,7 +50,7 @@ module ActionController
def new
# DEPRECATE Rails application fallback
- Rails.application
+ Rails.application.new
end
end
end
diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb
index ffce8e1bd1..654aa08cd3 100644
--- a/actionpack/lib/action_controller/metal/session_management.rb
+++ b/actionpack/lib/action_controller/metal/session_management.rb
@@ -16,7 +16,7 @@ module ActionController #:nodoc:
self.session_store = ActiveRecord::SessionStore
else
@@session_store = store.is_a?(Symbol) ?
- Session.const_get(store.to_s.camelize) :
+ ActionDispatch::Session.const_get(store.to_s.camelize) :
store
end
end
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index 38aaa6146e..11cd812695 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -39,6 +39,7 @@ module ActionDispatch
autoload :Rescue, 'action_dispatch/middleware/rescue'
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
autoload :Static, 'action_dispatch/middleware/static'
+ autoload :StringCoercion, 'action_dispatch/middleware/string_coercion'
autoload :Assertions, 'action_dispatch/testing/assertions'
autoload :Integration, 'action_dispatch/testing/integration'
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index cc989d6625..e85823d8db 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -10,7 +10,12 @@ module Mime
%w(<< concat shift unshift push pop []= clear compact! collect!
delete delete_at delete_if flatten! map! insert reject! reverse!
replace slice! sort! uniq!).each do |method|
- define_method(method) {|*args| @symbols = nil; super(*args) }
+ module_eval <<-CODE
+ def #{method}(*args)
+ @symbols = nil
+ super
+ end
+ CODE
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/string_coercion.rb b/actionpack/lib/action_dispatch/middleware/string_coercion.rb
new file mode 100644
index 0000000000..232e947835
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/string_coercion.rb
@@ -0,0 +1,29 @@
+module ActionDispatch
+ class StringCoercion
+ class UglyBody < ActiveSupport::BasicObject
+ def initialize(body)
+ @body = body
+ end
+
+ def each
+ @body.each do |part|
+ yield part.to_s
+ end
+ end
+
+ private
+ def method_missing(*args, &block)
+ @body.__send__(*args, &block)
+ end
+ end
+
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ status, headers, body = @app.call(env)
+ [status, headers, UglyBody.new(body)]
+ end
+ end
+end
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 3df4f2d6a3..e95e84aeb5 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -44,11 +44,11 @@ module ActionView
autoload :TextTemplate, 'action_view/template/text'
autoload :Helpers, 'action_view/helpers'
autoload :FileSystemResolverWithFallback, 'action_view/template/resolver'
+ autoload :SafeBuffer, 'action_view/safe_buffer'
end
-class ERB
- autoload :Util, 'action_view/erb/util'
-end
+require 'action_view/erb/util'
+
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index ec1b07797b..31e9c5ef9d 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -236,7 +236,16 @@ module ActionView #:nodoc:
# they are in AC.
if controller.class.respond_to?(:_helper_serial)
klass = @views[controller.class._helper_serial] ||= Class.new(self) do
- Subclasses.const_set(controller.class.name.gsub(/::/, '__'), self)
+ const_set(:CONTROLLER_CLASS, controller.class)
+
+ # Try to make stack traces clearer
+ def self.name
+ "ActionView for #{CONTROLLER_CLASS}"
+ end
+
+ def inspect
+ "#<#{self.class.name}>"
+ end
if controller.respond_to?(:_helpers)
include controller._helpers
@@ -255,7 +264,7 @@ module ActionView #:nodoc:
@assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) }
@controller = controller
@helpers = self.class.helpers || Module.new
- @_content_for = Hash.new {|h,k| h[k] = "" }
+ @_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new }
self.view_paths = view_paths
end
diff --git a/actionpack/lib/action_view/erb/util.rb b/actionpack/lib/action_view/erb/util.rb
index 3c77c5ce76..f767a5e27e 100644
--- a/actionpack/lib/action_view/erb/util.rb
+++ b/actionpack/lib/action_view/erb/util.rb
@@ -15,9 +15,19 @@ class ERB
# puts html_escape("is a > 0 & a < 10?")
# # => is a &gt; 0 &amp; a &lt; 10?
def html_escape(s)
- s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
+ s = s.to_s
+ if s.html_safe?
+ s
+ else
+ s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }.html_safe!
+ end
end
+ alias h html_escape
+
+ module_function :html_escape
+ module_function :h
+
# A utility method for escaping HTML entities in JSON strings.
# This method is also aliased as <tt>j</tt>.
#
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 652561f7f8..d63e8602f1 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -15,6 +15,7 @@ module ActionView #:nodoc:
autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper'
autoload :NumberHelper, 'action_view/helpers/number_helper'
autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
+ autoload :RawOutputHelper, 'action_view/helpers/raw_output_helper'
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
autoload :RecordTagHelper, 'action_view/helpers/record_tag_helper'
autoload :SanitizeHelper, 'action_view/helpers/sanitize_helper'
@@ -46,6 +47,7 @@ module ActionView #:nodoc:
include JavaScriptHelper
include NumberHelper
include PrototypeHelper
+ include RawOutputHelper
include RecordIdentificationHelper
include RecordTagHelper
include SanitizeHelper
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index 3e6e62237d..7cc1e48572 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -6,7 +6,7 @@ require 'active_support/core_ext/kernel/reporting'
module ActionView
class Base
- @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>" }
+ @@field_error_proc = Proc.new{ |html_tag, instance| "<div class=\"fieldWithErrors\">#{html_tag}</div>".html_safe! }
cattr_accessor :field_error_proc
end
@@ -91,6 +91,7 @@ module ActionView
yield contents if block_given?
contents << submit_tag(submit_value)
contents << '</form>'
+ contents.html_safe!
end
# Returns a string containing the error message attached to the +method+ on the +object+ if one exists.
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 95f00cda39..faa7f2e2e9 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -289,7 +289,7 @@ module ActionView
else
sources = expand_javascript_sources(sources, recursive)
ensure_javascript_sources!(sources) if cache
- sources.collect { |source| javascript_src_tag(source, options) }.join("\n")
+ sources.collect { |source| javascript_src_tag(source, options) }.join("\n").html_safe!
end
end
@@ -440,7 +440,7 @@ module ActionView
else
sources = expand_stylesheet_sources(sources, recursive)
ensure_stylesheet_sources!(sources) if cache
- sources.collect { |source| stylesheet_tag(source, options) }.join("\n")
+ sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe!
end
end
@@ -584,7 +584,7 @@ module ActionView
if sources.is_a?(Array)
content_tag("video", options) do
- sources.map { |source| tag("source", :src => source) }.join
+ sources.map { |source| tag("source", :src => source) }.join.html_safe!
end
else
options[:src] = path_to_video(sources)
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index c90acc5ac2..b62df75dbb 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -143,7 +143,7 @@ module ActionView
# Defaults to a new empty string.
def with_output_buffer(buf = nil) #:nodoc:
unless buf
- buf = ''
+ buf = ActionView::SafeBuffer.new
buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding)
end
self.output_buffer, old_buffer = buf, output_buffer
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 8a7a870b99..4b51dc7856 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -916,15 +916,15 @@ module ActionView
class InstanceTag #:nodoc:
def to_date_select_tag(options = {}, html_options = {})
- datetime_selector(options, html_options).select_date
+ datetime_selector(options, html_options).select_date.html_safe!
end
def to_time_select_tag(options = {}, html_options = {})
- datetime_selector(options, html_options).select_time
+ datetime_selector(options, html_options).select_time.html_safe!
end
def to_datetime_select_tag(options = {}, html_options = {})
- datetime_selector(options, html_options).select_datetime
+ datetime_selector(options, html_options).select_datetime.html_safe!
end
private
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 32b9c4a7dd..c46b39fc23 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -282,7 +282,7 @@ module ActionView
concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
fields_for(object_name, *(args << options), &proc)
- concat('</form>')
+ concat('</form>'.html_safe!)
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
@@ -809,7 +809,7 @@ module ActionView
add_default_name_and_id(options)
hidden = tag("input", "name" => options["name"], "type" => "hidden", "value" => options['disabled'] && checked ? checked_value : unchecked_value)
checkbox = tag("input", options)
- hidden + checkbox
+ (hidden + checkbox).html_safe!
end
def to_boolean_select_tag(options = {})
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 3db5202e7d..935ab5f3e8 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -296,7 +296,7 @@ module ActionView
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}>#{html_escape(text.to_s)}</option>)
end
- options_for_select.join("\n")
+ options_for_select.join("\n").html_safe!
end
# Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 1d851ecbd7..7688e786b1 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -440,7 +440,7 @@ module ActionView
concat(tag(:fieldset, options, true))
concat(content_tag(:legend, legend)) unless legend.blank?
concat(content)
- concat("</fieldset>")
+ concat("</fieldset>".html_safe!)
end
private
@@ -467,14 +467,14 @@ module ActionView
def form_tag_html(html_options)
extra_tags = extra_tags_for_form(html_options)
- tag(:form, html_options, true) + extra_tags
+ (tag(:form, html_options, true) + extra_tags).html_safe!
end
def form_tag_in_block(html_options, &block)
content = capture(&block)
concat(form_tag_html(html_options))
concat(content)
- concat("</form>")
+ concat("</form>".html_safe!)
end
def token_tag
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 897a7cc348..397871b85e 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/float/rounding'
module ActionView
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index 03f1dabb4e..8c1f0ad81f 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -395,7 +395,7 @@ module ActionView
concat(form_remote_tag(options))
fields_for(object_name, *(args << options), &proc)
- concat('</form>')
+ concat('</form>'.html_safe!)
end
alias_method :form_remote_for, :remote_form_for
diff --git a/actionpack/lib/action_view/helpers/raw_output_helper.rb b/actionpack/lib/action_view/helpers/raw_output_helper.rb
new file mode 100644
index 0000000000..79b0e4ee75
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/raw_output_helper.rb
@@ -0,0 +1,9 @@
+module ActionView #:nodoc:
+ module Helpers #:nodoc:
+ module RawOutputHelper
+ def raw(stringish)
+ stringish.to_s.html_safe!
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 0cdb70e217..31411dc08a 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -15,7 +15,7 @@ module ActionView
def div_for(record, *args, &block)
content_tag_for(:div, record, *args, &block)
end
-
+
# content_tag_for creates an HTML element with id and class parameters
# that relate to the specified Active Record object. For example:
#
@@ -34,7 +34,7 @@ module ActionView
# <% content_tag_for(:tr, @person, :foo) do %> ...
#
# produces:
- #
+ #
# <tr id="foo_person_123" class="person">...
#
# content_tag_for also accepts a hash of options, which will be converted to
@@ -50,7 +50,7 @@ module ActionView
def content_tag_for(tag_name, record, *args, &block)
prefix = args.first.is_a?(Hash) ? nil : args.shift
options = args.extract_options!
- options.merge!({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
+ options.merge!({ :class => "#{dom_class(record, prefix)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
content_tag(tag_name, options, &block)
end
end
diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb
index e93034d224..1f7ecc0ef8 100644
--- a/actionpack/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb
@@ -49,7 +49,11 @@ module ActionView
# confuse browsers.
#
def sanitize(html, options = {})
- self.class.white_list_sanitizer.sanitize(html, options)
+ returning self.class.white_list_sanitizer.sanitize(html, options) do |sanitized|
+ if sanitized
+ sanitized.html_safe!
+ end
+ end
end
# Sanitizes a block of CSS code. Used by +sanitize+ when it comes across a style attribute.
@@ -72,7 +76,11 @@ module ActionView
# strip_tags("<div id='top-bar'>Welcome to my website!</div>")
# # => Welcome to my website!
def strip_tags(html)
- self.class.full_sanitizer.sanitize(html)
+ returning self.class.full_sanitizer.sanitize(html) do |sanitized|
+ if sanitized
+ sanitized.html_safe!
+ end
+ end
end
# Strips all link tags from +text+ leaving just the link text.
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 7fae0f6b8d..ceddbd8cc1 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -41,7 +41,7 @@ module ActionView
# tag("img", { :src => "open &amp; shut.png" }, false, false)
# # => <img src="open &amp; shut.png" />
def tag(name, options = nil, open = false, escape = true)
- "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}"
+ "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe!
end
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
@@ -94,7 +94,7 @@ module ActionView
# cdata_section(File.read("hello_world.txt"))
# # => <![CDATA[<hello from a text file]]>
def cdata_section(content)
- "<![CDATA[#{content}]]>"
+ "<![CDATA[#{content}]]>".html_safe!
end
# Returns an escaped version of +html+ without affecting existing escaped entities.
@@ -128,7 +128,7 @@ module ActionView
def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
- "<#{name}#{tag_options}>#{content}</#{name}>"
+ "<#{name}#{tag_options}>#{content}</#{name}>".html_safe!
end
def tag_options(options, escape = true)
@@ -143,7 +143,7 @@ module ActionView
attrs << %(#{key}="#{final_value}")
end
end
- " #{attrs.sort * ' '}" unless attrs.empty?
+ " #{attrs.sort * ' '}".html_safe! unless attrs.empty?
end
end
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 204d4d71e1..e651bc17a9 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -93,7 +93,7 @@ module ActionView
polymorphic_path(options)
end
- escape ? escape_once(url) : url
+ (escape ? escape_once(url) : url).html_safe!
end
# Creates a link tag of the given +name+ using a URL created by the set
@@ -220,7 +220,7 @@ module ActionView
if block_given?
options = args.first || {}
html_options = args.second
- concat(link_to(capture(&block), options, html_options))
+ concat(link_to(capture(&block), options, html_options).html_safe!)
else
name = args[0]
options = args[1] || {}
@@ -238,7 +238,7 @@ module ActionView
end
href_attr = "href=\"#{url}\"" unless href
- "<a #{href_attr}#{tag_options}>#{name || url}</a>"
+ "<a #{href_attr}#{tag_options}>#{ERB::Util.h(name || url)}</a>".html_safe!
end
end
@@ -309,8 +309,8 @@ module ActionView
html_options.merge!("type" => "submit", "value" => name)
- "<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
- method_tag + tag("input", html_options) + request_token_tag + "</div></form>"
+ ("<form method=\"#{form_method}\" action=\"#{escape_once url}\" class=\"button-to\"><div>" +
+ method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe!
end
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 5524a3219a..23bde61f9c 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -1,8 +1,11 @@
module ActionView #:nodoc:
class PathSet < Array #:nodoc:
- def self.type_cast(obj)
+ def self.type_cast(obj, cache = nil)
+ # TODO: Clean this up
if obj.is_a?(String)
- cache = !defined?(Rails) || !Rails.respond_to?(:configuration) || Rails.configuration.cache_classes
+ if cache.nil?
+ cache = !defined?(Rails) || Rails.application.config.cache_classes
+ end
FileSystemResolverWithFallback.new(obj, :cache => cache)
else
obj
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index 7f10f54d2e..2eb88ae3e5 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -223,7 +223,7 @@ module ActionView
end
result = template ? collection_with_template(template) : collection_without_template
- result.join(spacer)
+ result.join(spacer).html_safe!
end
def collection_with_template(template)
@@ -296,7 +296,10 @@ module ActionView
end
def _find_template(path)
- prefix = @view.controller.controller_path unless path.include?(?/)
+ if controller = @view.controller
+ prefix = controller.controller_path unless path.include?(?/)
+ end
+
@view.find(path, {:formats => @view.formats}, prefix, true)
end
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index 0cab035ede..b6f5b9b6d1 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -14,6 +14,7 @@ module ActionView
case options
when Hash
layout = options[:layout]
+ options[:locals] ||= {}
if block_given?
return concat(_render_partial(options.merge(:partial => layout), &block))
@@ -25,11 +26,11 @@ module ActionView
if file = options[:file]
template = find(file, {:formats => formats})
- _render_template(template, layout, :locals => options[:locals] || {})
+ _render_template(template, layout, :locals => options[:locals])
elsif inline = options[:inline]
_render_inline(inline, layout, options)
elsif text = options[:text]
- _render_text(text, layout, options)
+ _render_text(text, layout, options[:locals])
end
when :update
update_page(&block)
@@ -80,16 +81,19 @@ module ActionView
def _render_inline(inline, layout, options)
handler = Template.handler_class_for_extension(options[:type] || "erb")
- template = Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
- locals = options[:locals] || {}
+ template = Template.new(options[:inline],
+ "inline #{options[:inline].inspect}", handler, {})
+
+ locals = options[:locals]
content = template.render(self, locals)
- content = layout.render(self, locals) {|*name| _layout_for(*name) { content } } if layout
- content
+ _render_text(content, layout, locals)
end
- def _render_text(text, layout, options)
- text = layout.render(self, options[:locals]) { text } if layout
- text
+ def _render_text(content, layout, locals)
+ content = layout.render(self, locals) do |*name|
+ _layout_for(*name) { content }
+ end if layout
+ content
end
# This is the API to render a ViewContext's template from a controller.
diff --git a/actionpack/lib/action_view/safe_buffer.rb b/actionpack/lib/action_view/safe_buffer.rb
new file mode 100644
index 0000000000..8ba9cd80d6
--- /dev/null
+++ b/actionpack/lib/action_view/safe_buffer.rb
@@ -0,0 +1,28 @@
+
+module ActionView #:nodoc:
+ class SafeBuffer < String
+ def <<(value)
+ if value.html_safe?
+ super(value)
+ else
+ super(CGI.escapeHTML(value))
+ end
+ end
+
+ def concat(value)
+ self << value
+ end
+
+ def html_safe?
+ true
+ end
+
+ def html_safe!
+ self
+ end
+
+ def to_s
+ self
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index aab7baf442..a780ab8d85 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -1,7 +1,31 @@
require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/string/output_safety'
+require 'erubis'
module ActionView
module TemplateHandlers
+ class Erubis < ::Erubis::Eruby
+ def add_preamble(src)
+ src << "@output_buffer = ActionView::SafeBuffer.new;"
+ end
+
+ def add_text(src, text)
+ src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
+ end
+
+ def add_expr_literal(src, code)
+ src << '@output_buffer << ((' << code << ').to_s);'
+ end
+
+ def add_expr_escaped(src, code)
+ src << '@output_buffer << ' << escaped_expr(code) << ';'
+ end
+
+ def add_postamble(src)
+ src << '@output_buffer.to_s'
+ end
+ end
+
class ERB < TemplateHandler
include Compilable
@@ -15,11 +39,9 @@ module ActionView
self.default_format = Mime::HTML
def compile(template)
- require 'erb'
-
magic = $1 if template.source =~ /\A(<%#.*coding[:=]\s*(\S+)\s*-?%>)/
erb = "#{magic}<% __in_erb_template=true %>#{template.source}"
- ::ERB.new(erb, nil, erb_trim_mode, '@output_buffer').src
+ Erubis.new(erb, :trim=>(self.class.erb_trim_mode == "-")).src
end
end
end
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index 441f462bc9..8beda24aba 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -55,7 +55,7 @@ module ActionView
setup :setup_with_controller
def setup_with_controller
@controller = TestController.new
- @output_buffer = ''
+ @output_buffer = ActionView::SafeBuffer.new
@rendered = ''
self.class.send(:include_helper_modules!)
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index aef3dd6165..4820f00aa1 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -51,23 +51,73 @@ I18n.backend.store_translations 'pt-BR', {}
ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
+FIXTURES = Pathname.new(FIXTURE_LOAD_PATH)
-class ActionController::IntegrationTest < ActiveSupport::TestCase
- @@app = ActionDispatch::MiddlewareStack.new { |middleware|
- middleware.use "ActionDispatch::ShowExceptions"
- middleware.use "ActionDispatch::Callbacks"
- middleware.use "ActionDispatch::ParamsParser"
- middleware.use "Rack::Head"
- }.build(ActionController::Routing::Routes)
-end
+module SetupOnce
+ extend ActiveSupport::Concern
-module ActionView
- class TestCase
- setup do
- ActionController::Routing::Routes.draw do |map|
- map.connect ':controller/:action/:id'
+ included do
+ cattr_accessor :setup_once_block
+ self.setup_once_block = nil
+
+ setup :run_setup_once
+ end
+
+ module ClassMethods
+ def setup_once(&block)
+ self.setup_once_block = block
+ end
+ end
+
+ private
+ def run_setup_once
+ if self.setup_once_block
+ self.setup_once_block.call
+ self.setup_once_block = nil
end
end
+end
+
+class ActiveSupport::TestCase
+ include SetupOnce
+
+ # Hold off drawing routes until all the possible controller classes
+ # have been loaded.
+ setup_once do
+ ActionController::Routing::Routes.draw do |map|
+ map.connect ':controller/:action/:id'
+ end
+ end
+end
+
+class ActionController::IntegrationTest < ActiveSupport::TestCase
+ def self.build_app(routes = nil)
+ ActionDispatch::MiddlewareStack.new { |middleware|
+ middleware.use "ActionDispatch::StringCoercion"
+ middleware.use "ActionDispatch::ShowExceptions"
+ middleware.use "ActionDispatch::Callbacks"
+ middleware.use "ActionDispatch::ParamsParser"
+ middleware.use "Rack::Head"
+ }.build(routes || ActionController::Routing::Routes)
+ end
+
+ self.app = build_app
+
+ def with_routing(&block)
+ real_routes = ActionController::Routing::Routes
+ ActionController::Routing.module_eval { remove_const :Routes }
+
+ temporary_routes = ActionController::Routing::RouteSet.new
+ self.class.app = self.class.build_app(temporary_routes)
+ ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
+
+ yield temporary_routes
+ ensure
+ if ActionController::Routing.const_defined? :Routes
+ ActionController::Routing.module_eval { remove_const :Routes }
+ end
+ ActionController::Routing.const_set(:Routes, real_routes) if real_routes
+ self.class.app = self.class.build_app
end
end
@@ -138,18 +188,12 @@ module ActionController
super
end
end
-
+
Base.view_paths = FIXTURE_LOAD_PATH
-
+
class TestCase
include TestProcess
- setup do
- ActionController::Routing::Routes.draw do |map|
- map.connect ':controller/:action/:id'
- end
- end
-
def assert_template(options = {}, message = nil)
validate_request!
@@ -192,11 +236,3 @@ module ActionController
end
end
end
-
-class SimpleRouteCase < Rack::TestCase
- setup do
- ActionController::Routing::Routes.draw do |map|
- map.connect ':controller/:action/:id'
- end
- end
-end
diff --git a/actionpack/test/activerecord/active_record_store_test.rb b/actionpack/test/activerecord/active_record_store_test.rb
index 102b9cffdd..c6c079f88c 100644
--- a/actionpack/test/activerecord/active_record_store_test.rb
+++ b/actionpack/test/activerecord/active_record_store_test.rb
@@ -158,7 +158,6 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
map.connect "/:action", :controller => "active_record_store_test/test"
end
@app = ActiveRecord::SessionStore.new(set, options.reverse_merge(:key => '_session_id'))
- reset!
yield
end
end
diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb
index 1a9f95e5e9..69b0eb5e3e 100644
--- a/actionpack/test/controller/caching_test.rb
+++ b/actionpack/test/controller/caching_test.rb
@@ -46,14 +46,8 @@ end
class PageCachingTest < ActionController::TestCase
def setup
super
- ActionController::Base.perform_caching = true
- ActionController::Routing::Routes.draw do |map|
- map.main '', :controller => 'posts', :format => nil
- map.formatted_posts 'posts.:format', :controller => 'posts'
- map.resources :posts
- map.connect ':controller/:action/:id'
- end
+ ActionController::Base.perform_caching = true
@request = ActionController::TestRequest.new
@request.host = 'hostname.com'
@@ -74,10 +68,16 @@ class PageCachingTest < ActionController::TestCase
end
def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
- @params[:format] = 'rss'
- assert_equal '/posts.rss', @rewriter.rewrite(@params)
- @params[:format] = nil
- assert_equal '/', @rewriter.rewrite(@params)
+ with_routing do |set|
+ set.draw do |map|
+ map.main '', :controller => 'posts', :format => nil
+ map.formatted_posts 'posts.:format', :controller => 'posts'
+ end
+ @params[:format] = 'rss'
+ assert_equal '/posts.rss', @rewriter.rewrite(@params)
+ @params[:format] = nil
+ assert_equal '/', @rewriter.rewrite(@params)
+ end
end
def test_should_cache_get_with_ok_status
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 0e4ca21143..508364d0b5 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -372,11 +372,8 @@ class IntegrationProcessTest < ActionController::IntegrationTest
def with_test_route_set
with_routing do |set|
set.draw do |map|
- map.with_options :controller => "IntegrationProcessTest::Integration" do |c|
- c.connect "/:action"
- end
+ map.connect "/:action", :controller => "integration_process_test/integration"
end
- reset!
yield
end
end
diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb
index 93a815adae..a79648396c 100644
--- a/actionpack/test/controller/mime_responds_test.rb
+++ b/actionpack/test/controller/mime_responds_test.rb
@@ -527,12 +527,6 @@ class RespondWithControllerTest < ActionController::TestCase
super
ActionController::Base.use_accept_header = true
@request.host = "www.example.com"
-
- ActionController::Routing::Routes.draw do |map|
- map.resources :customers
- map.resources :quiz_stores, :has_many => :customers
- map.connect ":controller/:action/:id"
- end
end
def teardown
@@ -593,53 +587,59 @@ class RespondWithControllerTest < ActionController::TestCase
end
def test_using_resource_for_post_with_html
- post :using_resource
- assert_equal "text/html", @response.content_type
- assert_equal 302, @response.status
- assert_equal "http://www.example.com/customers/13", @response.location
- assert @response.redirect?
-
- errors = { :name => :invalid }
- Customer.any_instance.stubs(:errors).returns(errors)
- post :using_resource
- assert_equal "text/html", @response.content_type
- assert_equal 200, @response.status
- assert_equal "New world!\n", @response.body
- assert_nil @response.location
+ with_test_route_set do
+ post :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal 302, @response.status
+ assert_equal "http://www.example.com/customers/13", @response.location
+ assert @response.redirect?
+
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+ post :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal 200, @response.status
+ assert_equal "New world!\n", @response.body
+ assert_nil @response.location
+ end
end
def test_using_resource_for_post_with_xml
- @request.accept = "application/xml"
-
- post :using_resource
- assert_equal "application/xml", @response.content_type
- assert_equal 201, @response.status
- assert_equal "<name>david</name>", @response.body
- assert_equal "http://www.example.com/customers/13", @response.location
-
- errors = { :name => :invalid }
- Customer.any_instance.stubs(:errors).returns(errors)
- post :using_resource
- assert_equal "application/xml", @response.content_type
- assert_equal 422, @response.status
- assert_equal errors.to_xml, @response.body
- assert_nil @response.location
+ with_test_route_set do
+ @request.accept = "application/xml"
+
+ post :using_resource
+ assert_equal "application/xml", @response.content_type
+ assert_equal 201, @response.status
+ assert_equal "<name>david</name>", @response.body
+ assert_equal "http://www.example.com/customers/13", @response.location
+
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+ post :using_resource
+ assert_equal "application/xml", @response.content_type
+ assert_equal 422, @response.status
+ assert_equal errors.to_xml, @response.body
+ assert_nil @response.location
+ end
end
def test_using_resource_for_put_with_html
- put :using_resource
- assert_equal "text/html", @response.content_type
- assert_equal 302, @response.status
- assert_equal "http://www.example.com/customers/13", @response.location
- assert @response.redirect?
-
- errors = { :name => :invalid }
- Customer.any_instance.stubs(:errors).returns(errors)
- put :using_resource
- assert_equal "text/html", @response.content_type
- assert_equal 200, @response.status
- assert_equal "Edit world!\n", @response.body
- assert_nil @response.location
+ with_test_route_set do
+ put :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal 302, @response.status
+ assert_equal "http://www.example.com/customers/13", @response.location
+ assert @response.redirect?
+
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+ put :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal 200, @response.status
+ assert_equal "Edit world!\n", @response.body
+ assert_nil @response.location
+ end
end
def test_using_resource_for_put_with_xml
@@ -660,11 +660,13 @@ class RespondWithControllerTest < ActionController::TestCase
end
def test_using_resource_for_delete_with_html
- Customer.any_instance.stubs(:destroyed?).returns(true)
- delete :using_resource
- assert_equal "text/html", @response.content_type
- assert_equal 302, @response.status
- assert_equal "http://www.example.com/customers", @response.location
+ with_test_route_set do
+ Customer.any_instance.stubs(:destroyed?).returns(true)
+ delete :using_resource
+ assert_equal "text/html", @response.content_type
+ assert_equal 302, @response.status
+ assert_equal "http://www.example.com/customers", @response.location
+ end
end
def test_using_resource_for_delete_with_xml
@@ -685,21 +687,23 @@ class RespondWithControllerTest < ActionController::TestCase
end
def test_using_resource_with_parent_for_post
- @request.accept = "application/xml"
-
- post :using_resource_with_parent
- assert_equal "application/xml", @response.content_type
- assert_equal 201, @response.status
- assert_equal "<name>david</name>", @response.body
- assert_equal "http://www.example.com/quiz_stores/11/customers/13", @response.location
-
- errors = { :name => :invalid }
- Customer.any_instance.stubs(:errors).returns(errors)
- post :using_resource
- assert_equal "application/xml", @response.content_type
- assert_equal 422, @response.status
- assert_equal errors.to_xml, @response.body
- assert_nil @response.location
+ with_test_route_set do
+ @request.accept = "application/xml"
+
+ post :using_resource_with_parent
+ assert_equal "application/xml", @response.content_type
+ assert_equal 201, @response.status
+ assert_equal "<name>david</name>", @response.body
+ assert_equal "http://www.example.com/quiz_stores/11/customers/13", @response.location
+
+ errors = { :name => :invalid }
+ Customer.any_instance.stubs(:errors).returns(errors)
+ post :using_resource
+ assert_equal "application/xml", @response.content_type
+ assert_equal 422, @response.status
+ assert_equal errors.to_xml, @response.body
+ assert_nil @response.location
+ end
end
def test_using_resource_with_collection
@@ -773,6 +777,18 @@ class RespondWithControllerTest < ActionController::TestCase
get :default_overwritten
assert_equal 406, @response.status
end
+
+ private
+ def with_test_route_set
+ with_routing do |set|
+ set.draw do |map|
+ map.resources :customers
+ map.resources :quiz_stores, :has_many => :customers
+ map.connect ":controller/:action/:id"
+ end
+ yield
+ end
+ end
end
class AbstractPostController < ActionController::Base
diff --git a/actionpack/test/new_base/base_test.rb b/actionpack/test/controller/new_base/base_test.rb
index effde324bc..1f9bf7f0fb 100644
--- a/actionpack/test/new_base/base_test.rb
+++ b/actionpack/test/controller/new_base/base_test.rb
@@ -26,7 +26,7 @@ module Dispatching
class ContainedEmptyController < ActionController::Base ; end
end
- class BaseTest < SimpleRouteCase
+ class BaseTest < Rack::TestCase
# :api: plugin
test "simple dispatching" do
get "/dispatching/simple/index"
diff --git a/actionpack/test/new_base/content_negotiation_test.rb b/actionpack/test/controller/new_base/content_negotiation_test.rb
index c43cb677f8..7b38a82f51 100644
--- a/actionpack/test/new_base/content_negotiation_test.rb
+++ b/actionpack/test/controller/new_base/content_negotiation_test.rb
@@ -9,7 +9,7 @@ module ContentNegotiation
)]
end
- class TestContentNegotiation < SimpleRouteCase
+ class TestContentNegotiation < Rack::TestCase
test "A */* Accept header will return HTML" do
get "/content_negotiation/basic/hello", {}, "HTTP_ACCEPT" => "*/*"
assert_body "Hello world */*!"
diff --git a/actionpack/test/new_base/content_type_test.rb b/actionpack/test/controller/new_base/content_type_test.rb
index 898d0bb9f3..0ff5552b08 100644
--- a/actionpack/test/new_base/content_type_test.rb
+++ b/actionpack/test/controller/new_base/content_type_test.rb
@@ -44,7 +44,7 @@ module ContentType
end
end
- class ExplicitContentTypeTest < SimpleRouteCase
+ class ExplicitContentTypeTest < Rack::TestCase
test "default response is HTML and UTF8" do
get "/content_type/base"
@@ -67,7 +67,7 @@ module ContentType
end
end
- class ImpliedContentTypeTest < SimpleRouteCase
+ class ImpliedContentTypeTest < Rack::TestCase
test "sets Content-Type as text/html when rendering *.html.erb" do
get "/content_type/implied/i_am_html_erb"
@@ -93,7 +93,7 @@ module ContentType
end
end
- class ExplicitCharsetTest < SimpleRouteCase
+ class ExplicitCharsetTest < Rack::TestCase
test "setting the charset of the response directly on the response object" do
get "/content_type/charset/set_on_response_obj"
diff --git a/actionpack/test/new_base/etag_test.rb b/actionpack/test/controller/new_base/etag_test.rb
index d5b7942ab6..51bfb2278a 100644
--- a/actionpack/test/new_base/etag_test.rb
+++ b/actionpack/test/controller/new_base/etag_test.rb
@@ -16,7 +16,7 @@ module Etags
end
end
- class EtagTest < SimpleRouteCase
+ class EtagTest < Rack::TestCase
describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text"
test "an action without a layout" do
diff --git a/actionpack/test/new_base/metal_test.rb b/actionpack/test/controller/new_base/metal_test.rb
index e1d46b906e..e1d46b906e 100644
--- a/actionpack/test/new_base/metal_test.rb
+++ b/actionpack/test/controller/new_base/metal_test.rb
diff --git a/actionpack/test/new_base/middleware_test.rb b/actionpack/test/controller/new_base/middleware_test.rb
index ada0215b1a..ada0215b1a 100644
--- a/actionpack/test/new_base/middleware_test.rb
+++ b/actionpack/test/controller/new_base/middleware_test.rb
diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/controller/new_base/render_action_test.rb
index d5896c1ebd..ecd29c4530 100644
--- a/actionpack/test/new_base/render_action_test.rb
+++ b/actionpack/test/controller/new_base/render_action_test.rb
@@ -45,7 +45,7 @@ module RenderAction
end
- class RenderActionTest < SimpleRouteCase
+ class RenderActionTest < Rack::TestCase
test "rendering an action using :action => <String>" do
get "/render_action/basic/hello_world"
@@ -82,7 +82,7 @@ module RenderAction
end
end
- class RenderLayoutTest < SimpleRouteCase
+ class RenderLayoutTest < Rack::TestCase
describe "Both <controller_path>.html.erb and application.html.erb are missing"
test "rendering with layout => true" do
@@ -150,7 +150,7 @@ module RenderActionWithApplicationLayout
end
end
- class LayoutTest < SimpleRouteCase
+ class LayoutTest < Rack::TestCase
describe "Only application.html.erb is present and <controller_path>.html.erb is missing"
test "rendering implicit application.html.erb as layout" do
@@ -189,7 +189,7 @@ module RenderActionWithApplicationLayout
end
end
- class TestLayout < SimpleRouteCase
+ class TestLayout < Rack::TestCase
testing BasicController
test "builder works with layouts" do
@@ -228,7 +228,7 @@ module RenderActionWithControllerLayout
end
end
- class ControllerLayoutTest < SimpleRouteCase
+ class ControllerLayoutTest < Rack::TestCase
describe "Only <controller_path>.html.erb is present and application.html.erb is missing"
test "render hello_world and implicitly use <controller_path>.html.erb as a layout." do
@@ -286,7 +286,7 @@ module RenderActionWithBothLayouts
end
end
- class ControllerLayoutTest < SimpleRouteCase
+ class ControllerLayoutTest < Rack::TestCase
describe "Both <controller_path>.html.erb and application.html.erb are present"
test "rendering implicitly use <controller_path>.html.erb over application.html.erb as a layout" do
diff --git a/actionpack/test/new_base/render_file_test.rb b/actionpack/test/controller/new_base/render_file_test.rb
index c4098855e6..8b2fdf8f96 100644
--- a/actionpack/test/new_base/render_file_test.rb
+++ b/actionpack/test/controller/new_base/render_file_test.rb
@@ -1,110 +1,99 @@
require 'abstract_unit'
module RenderFile
-
class BasicController < ActionController::Base
- self.view_paths = File.dirname(__FILE__)
-
+ self.view_paths = File.dirname(__FILE__)
+
def index
- render :file => File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world])
+ render :file => File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world])
end
-
+
def with_instance_variables
@secret = 'in the sauce'
- render :file => File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
+ render :file => File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb')
end
-
+
def without_file_key
- render File.join(File.dirname(__FILE__), *%w[.. fixtures test hello_world])
+ render File.join(File.dirname(__FILE__), *%w[.. .. fixtures test hello_world])
end
-
+
def without_file_key_with_instance_variable
@secret = 'in the sauce'
- render File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
+ render File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_ivar.erb')
end
-
+
def relative_path
@secret = 'in the sauce'
- render :file => '../fixtures/test/render_file_with_ivar'
+ render :file => '../../fixtures/test/render_file_with_ivar'
end
-
+
def relative_path_with_dot
@secret = 'in the sauce'
- render :file => '../fixtures/test/dot.directory/render_file_with_ivar'
+ render :file => '../../fixtures/test/dot.directory/render_file_with_ivar'
end
-
+
def pathname
@secret = 'in the sauce'
- render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. fixtures test dot.directory render_file_with_ivar.erb])
+ render :file => Pathname.new(File.dirname(__FILE__)).join(*%w[.. .. fixtures test dot.directory render_file_with_ivar.erb])
end
-
+
def with_locals
- path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_locals.erb')
+ path = File.join(File.dirname(__FILE__), '../../fixtures/test/render_file_with_locals.erb')
render :file => path, :locals => {:secret => 'in the sauce'}
end
-
+
def without_file_key_with_locals
- path = File.expand_path('../fixtures/test/render_file_with_locals.erb')
+ path = FIXTURES.join('test/render_file_with_locals.erb').to_s
render path, :locals => {:secret => 'in the sauce'}
end
end
-
- class TestBasic < SimpleRouteCase
+
+ class TestBasic < Rack::TestCase
testing RenderFile::BasicController
-
- def setup
- @old_pwd = Dir.pwd
- Dir.chdir(File.dirname(__FILE__))
- end
-
- def teardown
- Dir.chdir(@old_pwd)
- end
-
+
test "rendering simple template" do
get :index
assert_response "Hello world!"
end
-
+
test "rendering template with ivar" do
get :with_instance_variables
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering path without specifying the :file key" do
get :without_file_key
assert_response "Hello world!"
end
-
+
test "rendering path without specifying the :file key with ivar" do
get :without_file_key_with_instance_variable
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering a relative path" do
get :relative_path
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering a relative path with dot" do
get :relative_path_with_dot
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering a Pathname" do
get :pathname
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering file with locals" do
get :with_locals
assert_response "The secret is in the sauce\n"
end
-
+
test "rendering path without specifying the :file key with locals" do
get :without_file_key_with_locals
assert_response "The secret is in the sauce\n"
end
end
-
end
diff --git a/actionpack/test/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb
index 2b78fa7d4f..90cc7933ff 100644
--- a/actionpack/test/new_base/render_implicit_action_test.rb
+++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb
@@ -10,7 +10,7 @@ module RenderImplicitAction
def hello_world() end
end
- class RenderImplicitActionTest < SimpleRouteCase
+ class RenderImplicitActionTest < Rack::TestCase
test "render a simple action with new explicit call to render" do
get "/render_implicit_action/simple/hello_world"
diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/controller/new_base/render_layout_test.rb
index f840a47ecf..6a9668b81a 100644
--- a/actionpack/test/new_base/render_layout_test.rb
+++ b/actionpack/test/controller/new_base/render_layout_test.rb
@@ -36,7 +36,7 @@ module ControllerLayouts
end
end
- class RenderLayoutTest < SimpleRouteCase
+ class RenderLayoutTest < Rack::TestCase
test "rendering a normal template, but using the implicit layout" do
get "/controller_layouts/implicit/index"
@@ -58,7 +58,7 @@ module ControllerLayouts
end
- class LayoutOptionsTest < SimpleRouteCase
+ class LayoutOptionsTest < Rack::TestCase
testing ControllerLayouts::ImplicitController
test "rendering with :layout => false leaves out the implicit layout" do
@@ -79,7 +79,7 @@ module ControllerLayouts
end
end
- class MismatchFormatTest < SimpleRouteCase
+ class MismatchFormatTest < Rack::TestCase
testing ControllerLayouts::MismatchFormatController
test "if JS is selected, an HTML template is not also selected" do
diff --git a/actionpack/test/new_base/render_partial_test.rb b/actionpack/test/controller/new_base/render_partial_test.rb
index 7c2c20e1c7..8fddcbcd57 100644
--- a/actionpack/test/new_base/render_partial_test.rb
+++ b/actionpack/test/controller/new_base/render_partial_test.rb
@@ -15,7 +15,7 @@ module RenderPartial
end
end
- class TestPartial < SimpleRouteCase
+ class TestPartial < Rack::TestCase
testing BasicController
test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do
diff --git a/actionpack/test/new_base/render_rjs_test.rb b/actionpack/test/controller/new_base/render_rjs_test.rb
index 7b76c54ab9..8c47b38ab6 100644
--- a/actionpack/test/new_base/render_rjs_test.rb
+++ b/actionpack/test/controller/new_base/render_rjs_test.rb
@@ -21,7 +21,7 @@ module RenderRjs
end
end
- class TestBasic < SimpleRouteCase
+ class TestBasic < Rack::TestCase
testing BasicController
def setup
diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/controller/new_base/render_template_test.rb
index 3b24c2d75a..c81b951c0d 100644
--- a/actionpack/test/new_base/render_template_test.rb
+++ b/actionpack/test/controller/new_base/render_template_test.rb
@@ -39,7 +39,7 @@ module RenderTemplate
end
end
- class TestWithoutLayout < SimpleRouteCase
+ class TestWithoutLayout < Rack::TestCase
testing RenderTemplate::WithoutLayoutController
test "rendering a normal template with full path without layout" do
@@ -107,7 +107,7 @@ module RenderTemplate
end
end
- class TestWithLayout < SimpleRouteCase
+ class TestWithLayout < Rack::TestCase
describe "Rendering with :template using implicit or explicit layout"
test "rendering with implicit layout" do
@@ -158,7 +158,7 @@ module RenderTemplate
end
end
- class TestTemplateRenderWithForwardSlash < SimpleRouteCase
+ class TestTemplateRenderWithForwardSlash < Rack::TestCase
test "rendering a normal template with full path starting with a leading slash" do
get "/render_template/compatibility/without_layout/with_forward_slash"
diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/controller/new_base/render_test.rb
index 804be79d17..d985d9f9ad 100644
--- a/actionpack/test/new_base/render_test.rb
+++ b/actionpack/test/controller/new_base/render_test.rb
@@ -35,7 +35,7 @@ module Render
end
end
- class RenderTest < SimpleRouteCase
+ class RenderTest < Rack::TestCase
test "render with blank" do
get "/render/blank_render"
@@ -50,7 +50,7 @@ module Render
end
end
- class TestOnlyRenderPublicActions < SimpleRouteCase
+ class TestOnlyRenderPublicActions < Rack::TestCase
describe "Only public methods on actual controllers are callable actions"
test "raises an exception when a method of Object is called" do
@@ -66,7 +66,7 @@ module Render
end
end
- class TestVariousObjectsAvailableInView < SimpleRouteCase
+ class TestVariousObjectsAvailableInView < Rack::TestCase
test "The request object is accessible in the view" do
get "/render/blank_render/access_request"
assert_body "The request: GET"
diff --git a/actionpack/test/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb
index f5839ee16f..0e6f51c998 100644
--- a/actionpack/test/new_base/render_text_test.rb
+++ b/actionpack/test/controller/new_base/render_text_test.rb
@@ -62,7 +62,7 @@ module RenderText
end
end
- class RenderTextTest < SimpleRouteCase
+ class RenderTextTest < Rack::TestCase
describe "Rendering text using render :text"
test "rendering text from a action with default options renders the text with the layout" do
diff --git a/actionpack/test/new_base/render_xml_test.rb b/actionpack/test/controller/new_base/render_xml_test.rb
index d044738a78..d044738a78 100644
--- a/actionpack/test/new_base/render_xml_test.rb
+++ b/actionpack/test/controller/new_base/render_xml_test.rb
diff --git a/actionpack/test/controller/output_escaping_test.rb b/actionpack/test/controller/output_escaping_test.rb
new file mode 100644
index 0000000000..7332f3f1e3
--- /dev/null
+++ b/actionpack/test/controller/output_escaping_test.rb
@@ -0,0 +1,19 @@
+require 'abstract_unit'
+
+class OutputEscapingTest < ActiveSupport::TestCase
+
+ test "escape_html shouldn't die when passed nil" do
+ assert ERB::Util.h(nil).blank?
+ end
+
+ test "escapeHTML should escape strings" do
+ assert_equal "&lt;&gt;&quot;", ERB::Util.h("<>\"")
+ end
+
+ test "escapeHTML shouldn't touch explicitly safe strings" do
+ # TODO this seems easier to compose and reason about, but
+ # this should be verified
+ assert_equal "<", ERB::Util.h("<".html_safe!)
+ end
+
+end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index abcc8bf384..2db524ca4b 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1050,7 +1050,7 @@ class RenderTest < ActionController::TestCase
def test_action_talk_to_layout
get :action_talk_to_layout
- assert_equal "<title>Talking to the layout</title>\nAction was here!", @response.body
+ assert_equal "<title>Talking to the layout</title>\n\nAction was here!", @response.body
end
# :addressed:
diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb
index 6ad708bba1..689359166f 100644
--- a/actionpack/test/controller/rescue_test.rb
+++ b/actionpack/test/controller/rescue_test.rb
@@ -347,7 +347,6 @@ class RescueTest < ActionController::IntegrationTest
map.connect 'invalid', :controller => "rescue_test/test", :action => 'invalid'
map.connect 'b00m', :controller => "rescue_test/test", :action => 'b00m'
end
- reset!
yield
end
end
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 1aabf71cad..edf243337f 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -669,21 +669,13 @@ class LegacyRouteSetTests < Test::Unit::TestCase
%w(GET POST PUT DELETE).each do |request_method|
define_method("test_request_method_recognized_with_#{request_method}") do
- begin
- Object.const_set(:BooksController, Class.new(ActionController::Base))
-
- setup_request_method_routes_for(request_method)
-
- assert_nothing_raised { rs.recognize(@request) }
- assert_equal request_method.downcase, @request.path_parameters[:action]
- ensure
- Object.send(:remove_const, :BooksController) rescue nil
- end
+ setup_request_method_routes_for(request_method)
+ assert_nothing_raised { rs.recognize(@request) }
+ assert_equal request_method.downcase, @request.path_parameters[:action]
end
end
def test_recognize_array_of_methods
- Object.const_set(:BooksController, Class.new(ActionController::Base))
rs.draw do |r|
r.connect '/match', :controller => 'books', :action => 'get_or_post', :conditions => { :method => [:get, :post] }
r.connect '/match', :controller => 'books', :action => 'not_get_or_post'
@@ -701,13 +693,9 @@ class LegacyRouteSetTests < Test::Unit::TestCase
@request.request_uri = "/match"
assert_nothing_raised { rs.recognize(@request) }
assert_equal 'not_get_or_post', @request.path_parameters[:action]
- ensure
- Object.send(:remove_const, :BooksController) rescue nil
end
def test_subpath_recognized
- Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
-
rs.draw do |r|
r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
r.connect '/items/:id/:action', :controller => 'subpath_books'
@@ -730,13 +718,9 @@ class LegacyRouteSetTests < Test::Unit::TestCase
hash = rs.recognize_path "/posts/7"
assert_not_nil hash
assert_equal %w(subpath_books show 7), [hash[:controller], hash[:action], hash[:id]]
- ensure
- Object.send(:remove_const, :SubpathBooksController) rescue nil
end
def test_subpath_generated
- Object.const_set(:SubpathBooksController, Class.new(ActionController::Base))
-
rs.draw do |r|
r.connect '/books/:id/edit', :controller => 'subpath_books', :action => 'edit'
r.connect '/items/:id/:action', :controller => 'subpath_books'
@@ -746,8 +730,6 @@ class LegacyRouteSetTests < Test::Unit::TestCase
assert_equal "/books/7/edit", rs.generate(:controller => "subpath_books", :id => 7, :action => "edit")
assert_equal "/items/15/complete", rs.generate(:controller => "subpath_books", :id => 15, :action => "complete")
assert_equal "/posts/new/preview", rs.generate(:controller => "subpath_books", :action => "preview")
- ensure
- Object.send(:remove_const, :SubpathBooksController) rescue nil
end
def test_failed_requirements_raises_exception_with_violated_requirements
@@ -1122,8 +1104,6 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_recognize_with_conditions
- Object.const_set(:PeopleController, Class.new)
-
set.draw do |map|
map.with_options(:controller => "people") do |people|
people.people "/people", :action => "index", :conditions => { :method => :get }
@@ -1183,14 +1163,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_equal [:get, :put, :delete], e.allowed_methods
end
request.recycle!
-
- ensure
- Object.send(:remove_const, :PeopleController)
end
def test_recognize_with_alias_in_conditions
- Object.const_set(:PeopleController, Class.new)
-
set.draw do |map|
map.people "/people", :controller => 'people', :action => "index",
:conditions => { :method => :get }
@@ -1208,13 +1183,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("people", request.path_parameters[:controller])
assert_equal("index", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :PeopleController)
end
def test_typo_recognition
- Object.const_set(:ArticlesController, Class.new)
-
set.draw do |map|
map.connect 'articles/:year/:month/:day/:title',
:controller => 'articles', :action => 'permalink',
@@ -1229,9 +1200,6 @@ class RouteSetTest < ActiveSupport::TestCase
assert_equal("11", request.path_parameters[:month])
assert_equal("05", request.path_parameters[:day])
assert_equal("a-very-interesting-article", request.path_parameters[:title])
-
- ensure
- Object.send(:remove_const, :ArticlesController)
end
def test_routing_traversal_does_not_load_extra_classes
@@ -1248,8 +1216,6 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_recognize_with_conditions_and_format
- Object.const_set(:PeopleController, Class.new)
-
set.draw do |map|
map.with_options(:controller => "people") do |people|
people.person "/people/:id", :action => "show", :conditions => { :method => :get }
@@ -1276,8 +1242,6 @@ class RouteSetTest < ActiveSupport::TestCase
assert_equal("show", request.path_parameters[:action])
assert_equal("5", request.path_parameters[:id])
assert_equal("png", request.path_parameters[:_format])
- ensure
- Object.send(:remove_const, :PeopleController)
end
def test_generate_with_default_action
@@ -1291,8 +1255,6 @@ class RouteSetTest < ActiveSupport::TestCase
end
def test_root_map
- Object.const_set(:PeopleController, Class.new)
-
set.draw { |map| map.root :controller => "people" }
request.path = ""
@@ -1300,13 +1262,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("people", request.path_parameters[:controller])
assert_equal("index", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :PeopleController)
end
def test_namespace
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
-
set.draw do |map|
map.namespace 'api' do |api|
@@ -1320,13 +1278,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("api/products", request.path_parameters[:controller])
assert_equal("inventory", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :Api)
end
def test_namespaced_root_map
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
-
set.draw do |map|
map.namespace 'api' do |api|
@@ -1340,13 +1294,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("api/products", request.path_parameters[:controller])
assert_equal("index", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :Api)
end
def test_namespace_with_path_prefix
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
-
set.draw do |map|
map.namespace 'api', :path_prefix => 'prefix' do |api|
api.route 'inventory', :controller => "products", :action => 'inventory'
@@ -1358,13 +1308,9 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("api/products", request.path_parameters[:controller])
assert_equal("inventory", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :Api)
end
def test_namespace_with_blank_path_prefix
- Object.const_set(:Api, Module.new { |m| m.const_set(:ProductsController, Class.new) })
-
set.draw do |map|
map.namespace 'api', :path_prefix => '' do |api|
api.route 'inventory', :controller => "products", :action => 'inventory'
@@ -1376,8 +1322,6 @@ class RouteSetTest < ActiveSupport::TestCase
assert_nothing_raised { set.recognize(request) }
assert_equal("api/products", request.path_parameters[:controller])
assert_equal("inventory", request.path_parameters[:action])
- ensure
- Object.send(:remove_const, :Api)
end
def test_generate_changes_controller_module
diff --git a/actionpack/test/controller/verification_test.rb b/actionpack/test/controller/verification_test.rb
index ee558f3465..1a9eb65f29 100644
--- a/actionpack/test/controller/verification_test.rb
+++ b/actionpack/test/controller/verification_test.rb
@@ -111,13 +111,6 @@ class VerificationTest < ActionController::TestCase
tests TestController
- setup do
- ActionController::Routing::Routes.draw do |map|
- map.foo '/foo', :controller => 'test', :action => 'foo'
- map.connect ":controller/:action/:id"
- end
- end
-
def test_using_symbol_back_with_no_referrer
assert_raise(ActionController::RedirectBackError) { get :guarded_with_back }
end
@@ -130,8 +123,14 @@ class VerificationTest < ActionController::TestCase
def test_no_deprecation_warning_for_named_route
assert_not_deprecated do
- get :guarded_one_for_named_route_test, :two => "not one"
- assert_redirected_to '/foo'
+ with_routing do |set|
+ set.draw do |map|
+ map.foo '/foo', :controller => 'test', :action => 'foo'
+ map.connect ":controller/:action/:id"
+ end
+ get :guarded_one_for_named_route_test, :two => "not one"
+ assert_redirected_to '/foo'
+ end
end
end
diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb
index c04d20fbad..0514c098bf 100644
--- a/actionpack/test/controller/webservice_test.rb
+++ b/actionpack/test/controller/webservice_test.rb
@@ -259,7 +259,6 @@ class WebServiceTest < ActionController::IntegrationTest
c.connect "/", :action => "assign_parameters"
end
end
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb
index 995f36bb29..db6cf7b330 100644
--- a/actionpack/test/dispatch/request/json_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb
@@ -59,7 +59,6 @@ class JsonParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "json_params_parsing_test/test"
end
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
index d4ee4362eb..301080842e 100644
--- a/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/multipart_params_parsing_test.rb
@@ -153,7 +153,6 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "multipart_params_parsing_test/test"
end
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/query_string_parsing_test.rb b/actionpack/test/dispatch/request/query_string_parsing_test.rb
index 2261934e45..a31e326ddf 100644
--- a/actionpack/test/dispatch/request/query_string_parsing_test.rb
+++ b/actionpack/test/dispatch/request/query_string_parsing_test.rb
@@ -111,7 +111,6 @@ class QueryStringParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "query_string_parsing_test/test"
end
- reset!
get "/parse", actual
assert_response :ok
diff --git a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
index 6c9967d26e..7167cdafac 100644
--- a/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/url_encoded_params_parsing_test.rb
@@ -132,7 +132,6 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "url_encoded_params_parsing_test/test"
end
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/request/xml_params_parsing_test.rb b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
index 2f2dd695c4..521002b519 100644
--- a/actionpack/test/dispatch/request/xml_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/xml_params_parsing_test.rb
@@ -86,7 +86,6 @@ class XmlParamsParsingTest < ActionController::IntegrationTest
set.draw do |map|
map.connect ':action', :controller => "xml_params_parsing_test/test"
end
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index 6241c79829..ab5fabde65 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -223,7 +223,6 @@ class CookieStoreTest < ActionController::IntegrationTest
end
options = {:key => SessionKey, :secret => SessionSecret}.merge(options)
@app = ActionDispatch::Session::CookieStore.new(set, options)
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/session/mem_cache_store_test.rb b/actionpack/test/dispatch/session/mem_cache_store_test.rb
index c2d40ae24a..c7435bd06b 100644
--- a/actionpack/test/dispatch/session/mem_cache_store_test.rb
+++ b/actionpack/test/dispatch/session/mem_cache_store_test.rb
@@ -115,7 +115,6 @@ class MemCacheStoreTest < ActionController::IntegrationTest
map.connect "/:action", :controller => "mem_cache_store_test/test"
end
@app = ActionDispatch::Session::MemCacheStore.new(set, :key => '_session_id')
- reset!
yield
end
end
diff --git a/actionpack/test/dispatch/string_coercion_test.rb b/actionpack/test/dispatch/string_coercion_test.rb
new file mode 100644
index 0000000000..d79b17b932
--- /dev/null
+++ b/actionpack/test/dispatch/string_coercion_test.rb
@@ -0,0 +1,40 @@
+require 'abstract_unit'
+
+class StringCoercionTest < ActiveSupport::TestCase
+ test "body responds to each" do
+ original_body = []
+ body = ActionDispatch::StringCoercion::UglyBody.new(original_body)
+
+ assert original_body.respond_to?(:each)
+ assert body.respond_to?(:each)
+ end
+
+ test "body responds to to_path" do
+ original_body = []
+ def original_body.to_path; end
+ body = ActionDispatch::StringCoercion::UglyBody.new(original_body)
+
+ assert original_body.respond_to?(:to_path)
+ assert body.respond_to?(:to_path)
+ end
+
+ test "body does not responds to to_path" do
+ original_body = []
+ body = ActionDispatch::StringCoercion::UglyBody.new(original_body)
+
+ assert !original_body.respond_to?(:to_path)
+ assert !body.respond_to?(:to_path)
+ end
+
+ test "calls to_s on body parts" do
+ app = lambda { |env|
+ [200, {'Content-Type' => 'html'}, [1, 2, 3]]
+ }
+ app = ActionDispatch::StringCoercion.new(app)
+ parts = []
+ status, headers, body = app.call({})
+ body.each { |part| parts << part }
+
+ assert_equal %w( 1 2 3 ), parts
+ end
+end
diff --git a/actionpack/test/lib/controller/fake_controllers.rb b/actionpack/test/lib/controller/fake_controllers.rb
index 5dcca2e148..9ec7f330b8 100644
--- a/actionpack/test/lib/controller/fake_controllers.rb
+++ b/actionpack/test/lib/controller/fake_controllers.rb
@@ -1,22 +1,32 @@
class << Object; alias_method :const_available?, :const_defined?; end
-class ContentController < ActionController::Base
-end
-class NotAController
-end
+class ContentController < ActionController::Base; end
+class NotAController; end
+
module Admin
class << self; alias_method :const_available?, :const_defined?; end
class UserController < ActionController::Base; end
class NewsFeedController < ActionController::Base; end
end
-class ElsewhereController < ActionController::Base; end
+
+module Api
+ class ProductsController < ActionController::Base; end
+end
+
+# TODO: Reduce the number of test controllers we use
class AddressesController < ActionController::Base; end
-class SessionsController < ActionController::Base; end
-class FooController < ActionController::Base; end
+class ArticlesController < ActionController::Base; end
+class BarController < ActionController::Base; end
+class BooksController < ActionController::Base; end
+class BraveController < ActionController::Base; end
class CController < ActionController::Base; end
+class ElsewhereController < ActionController::Base; end
+class FooController < ActionController::Base; end
class HiController < ActionController::Base; end
-class BraveController < ActionController::Base; end
class ImageController < ActionController::Base; end
+class PeopleController < ActionController::Base; end
+class SessionsController < ActionController::Base; end
+class SubpathBooksController < ActionController::Base; end
class WeblogController < ActionController::Base; end
# For speed test
@@ -34,8 +44,3 @@ class ChannelsController < SpeedController; end
class ChannelVideosController < SpeedController; end
class LostPasswordsController < SpeedController; end
class PagesController < SpeedController; end
-
-ActionController::Routing::Routes.draw do |map|
- map.route_one 'route_one', :controller => 'elsewhere', :action => 'flash_me'
- map.connect ':controller/:action/:id'
-end
diff --git a/actionpack/test/lib/controller/fake_models.rb b/actionpack/test/lib/controller/fake_models.rb
index 18eff7516b..823de8bdc7 100644
--- a/actionpack/test/lib/controller/fake_models.rb
+++ b/actionpack/test/lib/controller/fake_models.rb
@@ -51,3 +51,99 @@ module Quiz
end
end
+class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ alias_method :secret?, :secret
+
+ def new_record=(boolean)
+ @new_record = boolean
+ end
+
+ def new_record?
+ @new_record
+ end
+
+ attr_accessor :author
+ def author_attributes=(attributes); end
+
+ attr_accessor :comments
+ def comments_attributes=(attributes); end
+
+ attr_accessor :tags
+ def tags_attributes=(attributes); end
+end
+
+class Comment
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ attr_reader :id
+ attr_reader :post_id
+ def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
+ def save; @id = 1; @post_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def name
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+
+ attr_accessor :relevances
+ def relevances_attributes=(attributes); end
+
+end
+
+class Tag
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ attr_reader :id
+ attr_reader :post_id
+ def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
+ def save; @id = 1; @post_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+
+ attr_accessor :relevances
+ def relevances_attributes=(attributes); end
+
+end
+
+class CommentRelevance
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ attr_reader :id
+ attr_reader :comment_id
+ def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
+ def save; @id = 1; @comment_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+end
+
+class TagRelevance
+ extend ActiveModel::Naming
+ include ActiveModel::Conversion
+
+ attr_reader :id
+ attr_reader :tag_id
+ def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
+ def save; @id = 1; @tag_id = 1 end
+ def new_record?; @id.nil? end
+ def to_param; @id; end
+ def value
+ @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
+ end
+end
+
+class Author < Comment
+ attr_accessor :post
+ def post_attributes=(attributes); end
+end
diff --git a/actionpack/test/javascript/ajax_test.rb b/actionpack/test/template/ajax_test.rb
index b67a91dad3..670ba92697 100644
--- a/actionpack/test/javascript/ajax_test.rb
+++ b/actionpack/test/template/ajax_test.rb
@@ -32,7 +32,7 @@ class LinkToRemoteTest < AjaxTestCase
end
test "with no update" do
- assert_html link, %w(href="/blog/destroy/3" Delete\ this\ post data-remote="true")
+ assert_html link, %w(href="/blog/destroy/4" Delete\ this\ post data-remote="true")
end
test "basic" do
@@ -46,7 +46,7 @@ class LinkToRemoteTest < AjaxTestCase
end
test "with :html options" do
- expected = %{<a href="/blog/destroy/3" data-custom="me" data-update-success="#posts">Delete this post</a>}
+ expected = %{<a href="/blog/destroy/4" data-custom="me" data-remote="true" data-update-success="#posts">Delete this post</a>}
assert_equal expected, link(:update => "#posts", :html => {"data-custom" => "me"})
end
@@ -74,7 +74,7 @@ class LinkToRemoteTest < AjaxTestCase
end
test "basic link_to_remote with :url =>" do
- expected = %{<a href="/blog/destroy/3" data-update-success="#posts">Delete this post</a>}
+ expected = %{<a href="/blog/destroy/3" data-remote="true" data-update-success="#posts">Delete this post</a>}
assert_equal expected,
link_to_remote("Delete this post", :url => "/blog/destroy/3", :update => "#posts")
end
@@ -93,7 +93,7 @@ class ButtonToRemoteTest < AjaxTestCase
def url_for(*)
"/whatnot"
end
-
+
class StandardTest < ButtonToRemoteTest
test "basic" do
button = button({:url => {:action => "whatnot"}}, {:class => "fine"})
@@ -103,13 +103,12 @@ class ButtonToRemoteTest < AjaxTestCase
end
end
end
-
+
class LegacyButtonToRemoteTest < ButtonToRemoteTest
include ActionView::Helpers::AjaxHelper::Rails2Compatibility
-
+
assert_callbacks_work do |callback|
button(callback => "undoRequestCompleted(request)")
end
end
-
-end \ No newline at end of file
+end
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 83fc6a282c..d94135b04b 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -231,6 +231,11 @@ class AssetTagHelperTest < ActionView::TestCase
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
end
+ def test_javascript_include_tag_is_html_safe
+ assert javascript_include_tag(:defaults).html_safe?
+ assert javascript_include_tag("prototype").html_safe?
+ end
+
def test_register_javascript_include_default
ENV["RAILS_ASSET_ID"] = ""
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'bank'
@@ -285,6 +290,13 @@ class AssetTagHelperTest < ActionView::TestCase
}
end
+ def test_stylesheet_link_tag_is_html_safe
+ ENV["RAILS_ASSET_ID"] = ""
+ assert stylesheet_link_tag('dir/file').html_safe?
+ assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
+ assert stylesheet_tag('dir/file', {}).html_safe?
+ end
+
def test_custom_stylesheet_expansions
ENV["RAILS_ASSET_ID"] = ''
ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :robbery => ["bank", "robber"]
diff --git a/actionpack/test/template/erb_util_test.rb b/actionpack/test/template/erb_util_test.rb
index 49f51c50c5..fa6b263965 100644
--- a/actionpack/test/template/erb_util_test.rb
+++ b/actionpack/test/template/erb_util_test.rb
@@ -15,6 +15,18 @@ class ErbUtilTest < Test::Unit::TestCase
end
end
+ def test_html_escape_is_html_safe
+ escaped = h("<p>")
+ assert_equal "&lt;p&gt;", escaped
+ assert escaped.html_safe?
+ end
+
+ def test_html_escape_passes_html_escpe_unmodified
+ escaped = h("<p>".html_safe!)
+ assert_equal "<p>", escaped
+ assert escaped.html_safe?
+ end
+
def test_rest_in_ascii
(0..127).to_a.map {|int| int.chr }.each do |chr|
next if %w(& " < >).include?(chr)
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index be15b06372..04c635e770 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -1,103 +1,5 @@
require 'abstract_unit'
-
-silence_warnings do
- class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- alias_method :secret?, :secret
-
- def new_record=(boolean)
- @new_record = boolean
- end
-
- def new_record?
- @new_record
- end
-
- attr_accessor :author
- def author_attributes=(attributes); end
-
- attr_accessor :comments
- def comments_attributes=(attributes); end
-
- attr_accessor :tags
- def tags_attributes=(attributes); end
- end
-
- class Comment
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def name
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class Tag
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- attr_reader :id
- attr_reader :post_id
- def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
- def save; @id = 1; @post_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
-
- attr_accessor :relevances
- def relevances_attributes=(attributes); end
-
- end
-
- class CommentRelevance
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- attr_reader :id
- attr_reader :comment_id
- def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
- def save; @id = 1; @comment_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class TagRelevance
- extend ActiveModel::Naming
- include ActiveModel::Conversion
-
- attr_reader :id
- attr_reader :tag_id
- def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
- def save; @id = 1; @tag_id = 1 end
- def new_record?; @id.nil? end
- def to_param; @id; end
- def value
- @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
- end
- end
-
- class Author < Comment
- attr_accessor :post
- def post_attributes=(attributes); end
- end
-end
+require 'controller/fake_models'
class FormHelperTest < ActionView::TestCase
tests ActionView::Helpers::FormHelper
@@ -1072,7 +974,7 @@ class FormHelperTest < ActionView::TestCase
(field_helpers - %w(hidden_field)).each do |selector|
src = <<-END_SRC
def #{selector}(field, *args, &proc)
- "<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>"
+ ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
end
END_SRC
class_eval src, __FILE__, __LINE__
diff --git a/actionpack/test/html-scanner/cdata_node_test.rb b/actionpack/test/template/html-scanner/cdata_node_test.rb
index 1822cc565a..1822cc565a 100644
--- a/actionpack/test/html-scanner/cdata_node_test.rb
+++ b/actionpack/test/template/html-scanner/cdata_node_test.rb
diff --git a/actionpack/test/html-scanner/document_test.rb b/actionpack/test/template/html-scanner/document_test.rb
index c68f04fa75..c68f04fa75 100644
--- a/actionpack/test/html-scanner/document_test.rb
+++ b/actionpack/test/template/html-scanner/document_test.rb
diff --git a/actionpack/test/html-scanner/node_test.rb b/actionpack/test/template/html-scanner/node_test.rb
index b0df36877e..b0df36877e 100644
--- a/actionpack/test/html-scanner/node_test.rb
+++ b/actionpack/test/template/html-scanner/node_test.rb
diff --git a/actionpack/test/html-scanner/sanitizer_test.rb b/actionpack/test/template/html-scanner/sanitizer_test.rb
index e85a5c7abf..e85a5c7abf 100644
--- a/actionpack/test/html-scanner/sanitizer_test.rb
+++ b/actionpack/test/template/html-scanner/sanitizer_test.rb
diff --git a/actionpack/test/html-scanner/tag_node_test.rb b/actionpack/test/template/html-scanner/tag_node_test.rb
index d1d4667378..d1d4667378 100644
--- a/actionpack/test/html-scanner/tag_node_test.rb
+++ b/actionpack/test/template/html-scanner/tag_node_test.rb
diff --git a/actionpack/test/html-scanner/text_node_test.rb b/actionpack/test/template/html-scanner/text_node_test.rb
index 1ab3f4454e..1ab3f4454e 100644
--- a/actionpack/test/html-scanner/text_node_test.rb
+++ b/actionpack/test/template/html-scanner/text_node_test.rb
diff --git a/actionpack/test/html-scanner/tokenizer_test.rb b/actionpack/test/template/html-scanner/tokenizer_test.rb
index a001bcbbad..a001bcbbad 100644
--- a/actionpack/test/html-scanner/tokenizer_test.rb
+++ b/actionpack/test/template/html-scanner/tokenizer_test.rb
diff --git a/actionpack/test/template/raw_output_helper_test.rb b/actionpack/test/template/raw_output_helper_test.rb
new file mode 100644
index 0000000000..598aa5b1d8
--- /dev/null
+++ b/actionpack/test/template/raw_output_helper_test.rb
@@ -0,0 +1,21 @@
+require 'abstract_unit'
+require 'testing_sandbox'
+
+class RawOutputHelperTest < ActionView::TestCase
+ tests ActionView::Helpers::RawOutputHelper
+ include TestingSandbox
+
+ def setup
+ @string = "hello"
+ end
+
+ test "raw returns the safe string" do
+ result = raw(@string)
+ assert_equal @string, result
+ assert result.html_safe?
+ end
+
+ test "raw handles nil values correctly" do
+ assert_equal "", raw(nil)
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/template/record_tag_helper_test.rb b/actionpack/test/template/record_tag_helper_test.rb
index 4144fea678..1cd18c0692 100644
--- a/actionpack/test/template/record_tag_helper_test.rb
+++ b/actionpack/test/template/record_tag_helper_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'controller/fake_models'
class Post
extend ActiveModel::Naming
@@ -26,7 +27,7 @@ class RecordTagHelperTest < ActionView::TestCase
end
def test_content_tag_for_prefix
- expected = %(<ul class="post" id="archived_post_45"></ul>)
+ expected = %(<ul class="archived_post" id="archived_post_45"></ul>)
actual = content_tag_for(:ul, @post, :archived) { }
assert_dom_equal expected, actual
end
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 3c192906ae..35c51ca7ea 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -229,7 +229,7 @@ module RenderTestCases
end
def test_render_with_nested_layout
- assert_equal %(<title>title</title>\n<div id="column">column</div>\n<div id="content">content</div>\n),
+ assert_equal %(<title>title</title>\n\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
@view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield")
end
diff --git a/actionpack/test/template/sanitize_helper_test.rb b/actionpack/test/template/sanitize_helper_test.rb
index f715071bbc..222d4dbf4c 100644
--- a/actionpack/test/template/sanitize_helper_test.rb
+++ b/actionpack/test/template/sanitize_helper_test.rb
@@ -39,7 +39,16 @@ class SanitizeHelperTest < ActionView::TestCase
%{This is a test.\n\n\nIt no longer contains any HTML.\n}, strip_tags(
%{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
assert_equal "This has a here.", strip_tags("This has a <!-- comment --> here.")
- [nil, '', ' '].each { |blank| assert_equal blank, strip_tags(blank) }
+ [nil, '', ' '].each do |blank|
+ stripped = strip_tags(blank)
+ assert_equal blank, stripped
+ assert stripped.html_safe? unless blank.nil?
+ end
+ assert strip_tags("<script>").html_safe?
+ end
+
+ def test_sanitize_is_marked_safe
+ assert sanitize("<html><script></script></html>").html_safe?
end
def assert_sanitized(text, expected = nil)
diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb
index 2aa3d5b5fa..433f6514cf 100644
--- a/actionpack/test/template/tag_helper_test.rb
+++ b/actionpack/test/template/tag_helper_test.rb
@@ -34,6 +34,7 @@ class TagHelperTest < ActionView::TestCase
def test_content_tag
assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create")
+ assert content_tag("a", "Create", "href" => "create").html_safe?
assert_equal content_tag("a", "Create", "href" => "create"),
content_tag("a", "Create", :href => "create")
end
diff --git a/actionpack/test/view/test_case_test.rb b/actionpack/test/template/test_case_test.rb
index 3e974b87f7..ca72c13ffa 100644
--- a/actionpack/test/view/test_case_test.rb
+++ b/actionpack/test/template/test_case_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'controller/fake_controllers'
module ActionView
class TestCase
@@ -154,7 +155,7 @@ module ActionView
class AssertionsTest < ActionView::TestCase
def render_from_helper
form_tag('/foo') do
- concat render(:text => '<ul><li>foo</li></ul>')
+ concat render(:text => '<ul><li>foo</li></ul>').html_safe!
end
end
helper_method :render_from_helper
diff --git a/actionpack/test/template/test_test.rb b/actionpack/test/template/test_test.rb
index f32d0b3d42..05a14f3554 100644
--- a/actionpack/test/template/test_test.rb
+++ b/actionpack/test/template/test_test.rb
@@ -19,32 +19,41 @@ module PeopleHelper
end
class PeopleHelperTest < ActionView::TestCase
- def setup
- super
- ActionController::Routing::Routes.draw do |map|
- map.people 'people', :controller => 'people', :action => 'index'
- map.connect ':controller/:action/:id'
- end
- end
-
def test_title
assert_equal "<h1>Ruby on Rails</h1>", title("Ruby on Rails")
end
def test_homepage_path
- assert_equal "/people", homepage_path
+ with_test_route_set do
+ assert_equal "/people", homepage_path
+ end
end
def test_homepage_url
- assert_equal "http://test.host/people", homepage_url
+ with_test_route_set do
+ assert_equal "http://test.host/people", homepage_url
+ end
end
def test_link_to_person
- person = mock(:name => "David")
- person.class.extend ActiveModel::Naming
- expects(:mocha_mock_path).with(person).returns("/people/1")
- assert_equal '<a href="/people/1">David</a>', link_to_person(person)
+ with_test_route_set do
+ person = mock(:name => "David")
+ person.class.extend ActiveModel::Naming
+ expects(:mocha_mock_path).with(person).returns("/people/1")
+ assert_equal '<a href="/people/1">David</a>', link_to_person(person)
+ end
end
+
+ private
+ def with_test_route_set
+ with_routing do |set|
+ set.draw do |map|
+ map.people 'people', :controller => 'people', :action => 'index'
+ map.connect ':controller/:action/:id'
+ end
+ yield
+ end
+ end
end
class CrazyHelperTest < ActionView::TestCase
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index ce99482078..7f6ebc56b7 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -139,7 +139,7 @@ class UrlHelperTest < ActionView::TestCase
end
def test_link_tag_with_img
- assert_dom_equal "<a href=\"http://www.example.com\"><img src='/favicon.jpg' /></a>", link_to("<img src='/favicon.jpg' />", "http://www.example.com")
+ assert_dom_equal "<a href=\"http://www.example.com\"><img src='/favicon.jpg' alt=\"Favicon\" /></a>", link_to(image_tag("/favicon.jpg"), "http://www.example.com")
end
def test_link_with_nil_html_options
diff --git a/actionpack/test/ts_isolated.rb b/actionpack/test/ts_isolated.rb
new file mode 100644
index 0000000000..21d62f6aa7
--- /dev/null
+++ b/actionpack/test/ts_isolated.rb
@@ -0,0 +1,17 @@
+$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
+
+require 'test/unit'
+require 'rbconfig'
+require 'active_support/core_ext/kernel/reporting'
+
+class TestIsolated < Test::Unit::TestCase
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+
+ Dir["#{File.dirname(__FILE__)}/{abstract,controller,dispatch,template}/**/*_test.rb"].each do |file|
+ define_method("test #{file}") do
+ command = "#{ruby} -Ilib:test #{file}"
+ silence_stderr { `#{command}` }
+ assert_equal 0, $?.to_i, command
+ end
+ end
+end
diff --git a/actionpack/test/view/safe_buffer_test.rb b/actionpack/test/view/safe_buffer_test.rb
new file mode 100644
index 0000000000..2236709627
--- /dev/null
+++ b/actionpack/test/view/safe_buffer_test.rb
@@ -0,0 +1,41 @@
+require 'abstract_unit'
+
+class SafeBufferTest < ActionView::TestCase
+ def setup
+ @buffer = ActionView::SafeBuffer.new
+ end
+
+ test "Should look like a string" do
+ assert @buffer.is_a?(String)
+ assert_equal "", @buffer
+ end
+
+ test "Should escape a raw string which is passed to them" do
+ @buffer << "<script>"
+ assert_equal "&lt;script&gt;", @buffer
+ end
+
+ test "Should NOT escape a safe value passed to it" do
+ @buffer << "<script>".html_safe!
+ assert_equal "<script>", @buffer
+ end
+
+ test "Should not mess with an innocuous string" do
+ @buffer << "Hello"
+ assert_equal "Hello", @buffer
+ end
+
+ test "Should not mess with a previously escape test" do
+ @buffer << CGI.escapeHTML("<script>")
+ assert_equal "&lt;script&gt;", @buffer
+ end
+
+ test "Should be considered safe" do
+ assert @buffer.html_safe?
+ end
+
+ test "Should return a safe buffer when calling to_s" do
+ new_buffer = @buffer.to_s
+ assert_equal ActionView::SafeBuffer, new_buffer.class
+ end
+end
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb
index aa35a2726e..977a101277 100644
--- a/activemodel/lib/active_model/attribute_methods.rb
+++ b/activemodel/lib/active_model/attribute_methods.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module ActiveModel
class MissingAttributeError < NoMethodError
end
@@ -162,6 +165,7 @@ module ActiveModel
end
end
end
+ @attribute_methods_generated = true
end
def undefine_attribute_methods
@@ -173,7 +177,6 @@ module ActiveModel
def generated_attribute_methods #:nodoc:
@generated_attribute_methods ||= begin
- @attribute_methods_generated = true
mod = Module.new
include mod
mod
@@ -219,7 +222,7 @@ module ActiveModel
end
def attribute_method_matchers #:nodoc:
- @@attribute_method_matchers ||= []
+ read_inheritable_attribute(:attribute_method_matchers) || write_inheritable_attribute(:attribute_method_matchers, [])
end
end
diff --git a/activemodel/lib/active_model/lint.rb b/activemodel/lib/active_model/lint.rb
index ceaa29dc8c..1c2347adbf 100644
--- a/activemodel/lib/active_model/lint.rb
+++ b/activemodel/lib/active_model/lint.rb
@@ -1,6 +1,6 @@
# You can test whether an object is compliant with the ActiveModel API by
-# calling ActiveModel::Lint.test(object). It will emit a Test::Unit
-# output that tells you whether your object is fully compliant, or if not,
+# including ActiveModel::Lint::Tests in your TestCase. It will included
+# tests that tell you whether your object is fully compliant, or if not,
# which aspects of the API are not implemented.
#
# These tests do not attempt to determine the semantic correctness of the
@@ -12,36 +12,15 @@
# call to to_model. It is perfectly fine for to_model to return self.
module ActiveModel
module Lint
- def self.test(object, verbosity = 2, output = STDOUT)
- require "test/unit"
- require "test/unit/ui/console/testrunner"
-
- test_class = Class.new(::Test::Unit::TestCase) do
- include Test
-
- define_method(:setup) do
- assert object.respond_to?(:to_model), "The object should respond_to :to_model"
- @object = object.to_model
- super
- end
- end
-
- ::Test::Unit::UI::Console::TestRunner.new(test_class, verbosity, output).start
- end
-
- module Test
- def assert_boolean(name, result)
- assert result == true || result == false, "#{name} should be a boolean"
- end
-
+ module Tests
# valid?
# ------
#
# Returns a boolean that specifies whether the object is in a valid or invalid
# state.
def test_valid?
- assert @object.respond_to?(:valid?), "The model should respond to valid?"
- assert_boolean "valid?", @object.valid?
+ assert model.respond_to?(:valid?), "The model should respond to valid?"
+ assert_boolean model.valid?, "valid?"
end
# new_record?
@@ -53,13 +32,13 @@ module ActiveModel
# collection. If it is persisted, a form for the object will put PUTed to the
# URL for the object.
def test_new_record?
- assert @object.respond_to?(:new_record?), "The model should respond to new_record?"
- assert_boolean "new_record?", @object.new_record?
+ assert model.respond_to?(:new_record?), "The model should respond to new_record?"
+ assert_boolean model.new_record?, "new_record?"
end
def test_destroyed?
- assert @object.respond_to?(:destroyed?), "The model should respond to destroyed?"
- assert_boolean "destroyed?", @object.destroyed?
+ assert model.respond_to?(:destroyed?), "The model should respond to destroyed?"
+ assert_boolean model.destroyed?, "destroyed?"
end
# errors
@@ -67,29 +46,32 @@ module ActiveModel
#
# Returns an object that has :[] and :full_messages defined on it. See below
# for more details.
- def setup
- assert @object.respond_to?(:errors), "The model should respond to errors"
- @errors = @object.errors
+
+ # Returns an Array of Strings that are the errors for the attribute in
+ # question. If localization is used, the Strings should be localized
+ # for the current locale. If no error is present, this method should
+ # return an empty Array.
+ def test_errors_aref
+ assert model.respond_to?(:errors), "The model should respond to errors"
+ assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array"
end
- # This module tests the #errors object
- module Errors
- # Returns an Array of Strings that are the errors for the attribute in
- # question. If localization is used, the Strings should be localized
- # for the current locale. If no error is present, this method should
- # return an empty Array.
- def test_errors_aref
- assert @errors[:hello].is_a?(Array), "errors#[] should return an Array"
- end
+ # Returns an Array of all error messages for the object. Each message
+ # should contain information about the field, if applicable.
+ def test_errors_full_messages
+ assert model.respond_to?(:errors), "The model should respond to errors"
+ assert model.errors.full_messages.is_a?(Array), "errors#full_messages should return an Array"
+ end
- # Returns an Array of all error messages for the object. Each message
- # should contain information about the field, if applicable.
- def test_errors_full_messages
- assert @errors.full_messages.is_a?(Array), "errors#full_messages should return an Array"
+ private
+ def model
+ assert @model.respond_to?(:to_model), "The object should respond_to to_model"
+ @model.to_model
end
- end
- include Errors
+ def assert_boolean(result, name)
+ assert result == true || result == false, "#{name} should be a boolean"
+ end
end
end
end
diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb
new file mode 100644
index 0000000000..5659dcbc48
--- /dev/null
+++ b/activemodel/test/cases/attribute_methods_test.rb
@@ -0,0 +1,46 @@
+require 'cases/helper'
+
+class ModelWithAttributes
+ include ActiveModel::AttributeMethods
+
+ attribute_method_suffix ''
+
+ def attributes
+ { :foo => 'value of foo' }
+ end
+
+private
+ def attribute(name)
+ attributes[name.to_sym]
+ end
+end
+
+class ModelWithAttributes2
+ include ActiveModel::AttributeMethods
+
+ attribute_method_suffix '_test'
+end
+
+class AttributeMethodsTest < ActiveModel::TestCase
+ test 'unrelated classes should not share attribute method matchers' do
+ assert_not_equal ModelWithAttributes.send(:attribute_method_matchers),
+ ModelWithAttributes2.send(:attribute_method_matchers)
+ end
+
+ test '#define_attribute_methods generates attribute methods' do
+ ModelWithAttributes.define_attribute_methods([:foo])
+
+ assert ModelWithAttributes.attribute_methods_generated?
+ assert ModelWithAttributes.new.respond_to?(:foo)
+ assert_equal "value of foo", ModelWithAttributes.new.foo
+ end
+
+ test '#undefine_attribute_methods removes attribute methods' do
+ ModelWithAttributes.define_attribute_methods([:foo])
+ ModelWithAttributes.undefine_attribute_methods
+
+ assert !ModelWithAttributes.attribute_methods_generated?
+ assert !ModelWithAttributes.new.respond_to?(:foo)
+ assert_raises(NoMethodError) { ModelWithAttributes.new.foo }
+ end
+end
diff --git a/activemodel/test/cases/lint_test.rb b/activemodel/test/cases/lint_test.rb
index ed576a91e2..da7d2112dc 100644
--- a/activemodel/test/cases/lint_test.rb
+++ b/activemodel/test/cases/lint_test.rb
@@ -1,15 +1,17 @@
require "cases/helper"
-class TestLint < ActiveModel::TestCase
- class CompliantObject
+class LintTest < ActiveModel::TestCase
+ include ActiveModel::Lint::Tests
+
+ class CompliantModel
def to_model
self
end
-
+
def valid?() true end
def new_record?() true end
def destroyed?() true end
-
+
def errors
obj = Object.new
def obj.[](key) [] end
@@ -17,34 +19,8 @@ class TestLint < ActiveModel::TestCase
obj
end
end
-
- def assert_output(object, failures, errors, *test_names)
- ActiveModel::Lint.test(object, 3, output = StringIO.new)
- regex = %r{#{failures} failures, #{errors} errors}
- assert_match regex, output.string
-
- test_names.each do |test_name|
- assert_match test_name, output.string
- end
- end
-
- def test_valid
- assert_output(CompliantObject.new, 0, 0, /test_valid/)
- end
-
- def test_new_record
- assert_output(CompliantObject.new, 0, 0, /test_new_record?/)
- end
-
- def test_destroyed
- assert_output(CompliantObject.new, 0, 0, /test_destroyed/)
- end
-
- def test_errors_aref
- assert_output(CompliantObject.new, 0, 0, /test_errors_aref/)
- end
- def test_errors_full_messages
- assert_output(CompliantObject.new, 0, 0, /test_errors_aref/)
+ def setup
+ @model = CompliantModel.new
end
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 502fe0442e..150e3fc263 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -2427,6 +2427,29 @@ module ActiveRecord #:nodoc:
result
end
+ # Cloned objects have no id assigned and are treated as new records. Note that this is a "shallow" clone
+ # as it copies the object's attributes only, not its associations. The extent of a "deep" clone is
+ # application specific and is therefore left to the application to implement according to its need.
+ def initialize_copy(other)
+ # Think the assertion which fails if the after_initialize callback goes at the end of the method is wrong. The
+ # deleted clone method called new which therefore called the after_initialize callback. It then went on to copy
+ # over the attributes. But if it's copying the attributes afterwards then it hasn't finished initializing right?
+ # For example in the test suite the topic model's after_initialize method sets the author_email_address to
+ # test@test.com. I would have thought this would mean that all cloned models would have an author email address
+ # of test@test.com. However the test_clone test method seems to test that this is not the case. As a result the
+ # after_initialize callback has to be run *before* the copying of the atrributes rather than afterwards in order
+ # for all tests to pass. This makes no sense to me.
+ callback(:after_initialize) if respond_to_without_attributes?(:after_initialize)
+ cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast)
+ cloned_attributes.delete(self.class.primary_key)
+ @attributes = cloned_attributes
+ clear_aggregation_cache
+ @attributes_cache = {}
+ @new_record = true
+ ensure_proper_type
+ self.class.send(:scope, :create).each { |att, value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create)
+ end
+
# Returns a String, which Action Pack uses for constructing an URL to this
# object. The default implementation returns this record's id as a String,
# or nil if this record's unsaved.
@@ -2555,19 +2578,6 @@ module ActiveRecord #:nodoc:
freeze
end
- # Returns a clone of the record that hasn't been assigned an id yet and
- # is treated as a new record. Note that this is a "shallow" clone:
- # it copies the object's attributes only, not its associations.
- # The extent of a "deep" clone is application-specific and is therefore
- # left to the application to implement according to its need.
- def clone
- attrs = clone_attributes(:read_attribute_before_type_cast)
- attrs.delete(self.class.primary_key)
- record = self.class.new
- record.send :instance_variable_set, '@attributes', attrs
- record
- end
-
# Returns an instance of the specified +klass+ with the attributes of the current record. This is mostly useful in relation to
# single-table inheritance structures where you want a subclass to appear as the superclass. This can be used along with record
# identification in Action Pack to allow, say, <tt>Client < Company</tt> to do something like render <tt>:partial => @client.becomes(Company)</tt>
@@ -2831,6 +2841,21 @@ module ActiveRecord #:nodoc:
"#<#{self.class} #{attributes_as_nice_string}>"
end
+ protected
+ def clone_attributes(reader_method = :read_attribute, attributes = {})
+ self.attribute_names.inject(attributes) do |attrs, name|
+ attrs[name] = clone_attribute_value(reader_method, name)
+ attrs
+ end
+ end
+
+ def clone_attribute_value(reader_method, attribute_name)
+ value = send(reader_method, attribute_name)
+ value.duplicable? ? value.clone : value
+ rescue TypeError, NoMethodError
+ value
+ end
+
private
def create_or_update
raise ReadOnlyRecord if readonly?
@@ -3093,20 +3118,6 @@ module ActiveRecord #:nodoc:
return string unless string.is_a?(String) && string =~ /^---/
YAML::load(string) rescue string
end
-
- def clone_attributes(reader_method = :read_attribute, attributes = {})
- self.attribute_names.inject(attributes) do |attrs, name|
- attrs[name] = clone_attribute_value(reader_method, name)
- attrs
- end
- end
-
- def clone_attribute_value(reader_method, attribute_name)
- value = send(reader_method, attribute_name)
- value.duplicable? ? value.clone : value
- rescue TypeError, NoMethodError
- value
- end
end
Base.class_eval do
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 9c29f32639..f65ee9465e 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -3,11 +3,14 @@ require 'active_support/core_ext/object/try'
module ActiveRecord
module NestedAttributes #:nodoc:
+ class TooManyRecords < ActiveRecordError
+ end
+
extend ActiveSupport::Concern
included do
- class_inheritable_accessor :reject_new_nested_attributes_procs, :instance_writer => false
- self.reject_new_nested_attributes_procs = {}
+ class_inheritable_accessor :nested_attributes_options, :instance_writer => false
+ self.nested_attributes_options = {}
end
# == Nested Attributes
@@ -127,6 +130,22 @@ module ActiveRecord
# member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
# member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
#
+ # Alternatively, :reject_if also accepts a symbol for using methods:
+ #
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :new_record?
+ # end
+ #
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :reject_posts
+ #
+ # def reject_posts(attributed)
+ # attributed['title].blank?
+ # end
+ # end
+ #
# If the hash contains an <tt>id</tt> key that matches an already
# associated record, the matching record will be modified:
#
@@ -179,13 +198,20 @@ module ActiveRecord
# <tt>_destroy</tt> key and a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'). This option is off by default.
# [:reject_if]
- # Allows you to specify a Proc that checks whether a record should be
- # built for a certain attribute hash. The hash is passed to the Proc
- # and the Proc should return either +true+ or +false+. When no Proc
- # is specified a record will be built for all attribute hashes that
+ # Allows you to specify a Proc or a Symbol pointing to a method
+ # that checks whether a record should be built for a certain attribute
+ # hash. The hash is passed to the supplied Proc or the method
+ # and it should return either +true+ or +false+. When no :reject_if
+ # is specified, a record will be built for all attribute hashes that
# do not have a <tt>_destroy</tt> value that evaluates to true.
# Passing <tt>:all_blank</tt> instead of a Proc will create a proc
# that will reject a record where all the attributes are blank.
+ # [:limit]
+ # Allows you to specify the maximum number of the associated records that
+ # can be processes with the nested attributes. If the size of the
+ # nested attributes array exceeds the specified limit, NestedAttributes::TooManyRecords
+ # exception is raised. If omitted, any number associations can be processed.
+ # Note that the :limit option is only applicable to one-to-many associations.
#
# Examples:
# # creates avatar_attributes=
@@ -197,7 +223,7 @@ module ActiveRecord
def accepts_nested_attributes_for(*attr_names)
options = { :allow_destroy => false }
options.update(attr_names.extract_options!)
- options.assert_valid_keys(:allow_destroy, :reject_if)
+ options.assert_valid_keys(:allow_destroy, :reject_if, :limit)
attr_names.each do |association_name|
if reflection = reflect_on_association(association_name)
@@ -210,10 +236,10 @@ module ActiveRecord
reflection.options[:autosave] = true
- self.reject_new_nested_attributes_procs[association_name.to_sym] = if options[:reject_if] == :all_blank
- proc { |attributes| attributes.all? {|k,v| v.blank?} }
- else
- options[:reject_if]
+ self.nested_attributes_options[association_name.to_sym] = options
+
+ if options[:reject_if] == :all_blank
+ self.nested_attributes_options[association_name.to_sym][:reject_if] = proc { |attributes| attributes.all? {|k,v| v.blank?} }
end
# def pirate_attributes=(attributes)
@@ -221,7 +247,7 @@ module ActiveRecord
# end
class_eval %{
def #{association_name}_attributes=(attributes)
- assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes, #{options[:allow_destroy]})
+ assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
end
}, __FILE__, __LINE__
else
@@ -265,8 +291,9 @@ module ActiveRecord
# If the given attributes include a matching <tt>:id</tt> attribute _and_ a
# <tt>:_destroy</tt> key set to a truthy value, then the existing record
# will be marked for destruction.
- def assign_nested_attributes_for_one_to_one_association(association_name, attributes, allow_destroy)
- attributes = attributes.stringify_keys
+ def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
+ options = self.nested_attributes_options[association_name]
+ attributes = attributes.with_indifferent_access
if attributes['id'].blank?
unless reject_new_record?(association_name, attributes)
@@ -278,7 +305,7 @@ module ActiveRecord
end
end
elsif (existing_record = send(association_name)) && existing_record.id.to_s == attributes['id'].to_s
- assign_to_or_mark_for_destruction(existing_record, attributes, allow_destroy)
+ assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
end
end
@@ -309,24 +336,30 @@ module ActiveRecord
# { :name => 'John' },
# { :id => '2', :_destroy => true }
# ])
- def assign_nested_attributes_for_collection_association(association_name, attributes_collection, allow_destroy)
+ def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
+ options = self.nested_attributes_options[association_name]
+
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
end
+ if options[:limit] && attributes_collection.size > options[:limit]
+ raise TooManyRecords, "Maximum #{options[:limit]} records are allowed. Got #{attributes_collection.size} records instead."
+ end
+
if attributes_collection.is_a? Hash
attributes_collection = attributes_collection.sort_by { |index, _| index.to_i }.map { |_, attributes| attributes }
end
attributes_collection.each do |attributes|
- attributes = attributes.stringify_keys
+ attributes = attributes.with_indifferent_access
if attributes['id'].blank?
unless reject_new_record?(association_name, attributes)
send(association_name).build(attributes.except(*UNASSIGNABLE_KEYS))
end
elsif existing_record = send(association_name).detect { |record| record.id.to_s == attributes['id'].to_s }
- assign_to_or_mark_for_destruction(existing_record, attributes, allow_destroy)
+ assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
end
end
end
@@ -351,8 +384,18 @@ module ActiveRecord
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
# association and evaluates to +true+.
def reject_new_record?(association_name, attributes)
- has_destroy_flag?(attributes) ||
- self.class.reject_new_nested_attributes_procs[association_name].try(:call, attributes)
+ has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
+ end
+
+ def call_reject_if(association_name, attributes)
+ callback = self.nested_attributes_options[association_name][:reject_if]
+
+ case callback
+ when Symbol
+ method(callback).arity == 0 ? send(callback) : send(callback, attributes)
+ when Proc
+ callback.try(:call, attributes)
+ end
end
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 8421a8fb07..1e2d903492 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -1352,7 +1352,7 @@ class BasicsTest < ActiveRecord::TestCase
cloned_topic.title["a"] = "c"
assert_equal "b", topic.title["a"]
- #test if attributes set as part of after_initialize are cloned correctly
+ # test if attributes set as part of after_initialize are cloned correctly
assert_equal topic.author_email_address, cloned_topic.author_email_address
# test if saved clone object differs from original
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index 721792132c..53fd168e1b 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -29,13 +29,13 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
end
- def test_base_should_have_an_empty_reject_new_nested_attributes_procs
- assert_equal Hash.new, ActiveRecord::Base.reject_new_nested_attributes_procs
+ def test_base_should_have_an_empty_nested_attributes_options
+ assert_equal Hash.new, ActiveRecord::Base.nested_attributes_options
end
- def test_should_add_a_proc_to_reject_new_nested_attributes_procs
+ def test_should_add_a_proc_to_nested_attributes_options
[:parrots, :birds, :birds_with_reject_all_blank].each do |name|
- assert_instance_of Proc, Pirate.reject_new_nested_attributes_procs[name]
+ assert_instance_of Proc, Pirate.nested_attributes_options[name][:reject_if]
end
end
@@ -84,6 +84,34 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
ship = Ship.create!(:name => 'Nights Dirty Lightning')
ship._delete
end
+
+ def test_reject_if_method_without_arguments
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => :new_record?
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :name => 'Black Pearl' }
+ assert_no_difference('Ship.count') { pirate.save! }
+ end
+
+ def test_reject_if_method_with_arguments
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => :reject_empty_ships_on_create
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
+ assert_no_difference('Ship.count') { pirate.save! }
+
+ # pirate.reject_empty_ships_on_create returns false for saved records
+ pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
+ assert_difference('Ship.count') { pirate.save! }
+ end
+
+ def test_reject_if_with_indifferent_keys
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => proc {|attributes| attributes[:name].blank? }
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :name => 'Hello Pearl' }
+ assert_difference('Ship.count') { pirate.save! }
+ end
end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@@ -575,3 +603,33 @@ class TestNestedAttributesOnAHasAndBelongsToManyAssociation < ActiveRecord::Test
include NestedAttributesOnACollectionAssociationTests
end
+
+class TestNestedAttributesLimit < ActiveRecord::TestCase
+ def setup
+ Pirate.accepts_nested_attributes_for :parrots, :limit => 2
+
+ @pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
+ end
+
+ def teardown
+ Pirate.accepts_nested_attributes_for :parrots, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
+ end
+
+ def test_limit_with_less_records
+ @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Big Big Love' } } }
+ assert_difference('Parrot.count') { @pirate.save! }
+ end
+
+ def test_limit_with_number_exact_records
+ @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Lovely Day' }, 'bar' => { :name => 'Blown Away' } } }
+ assert_difference('Parrot.count', 2) { @pirate.save! }
+ end
+
+ def test_limit_with_exceeding_records
+ assert_raises(ActiveRecord::NestedAttributes::TooManyRecords) do
+ @pirate.attributes = { :parrots_attributes => { 'foo' => { :name => 'Lovely Day' },
+ 'bar' => { :name => 'Blown Away' },
+ 'car' => { :name => 'The Happening' }} }
+ end
+ end
+end
diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb
index 3d7c4bc48a..05c5b666ae 100644
--- a/activerecord/test/models/pirate.rb
+++ b/activerecord/test/models/pirate.rb
@@ -45,6 +45,10 @@ class Pirate < ActiveRecord::Base
@ship_log ||= []
end
+ def reject_empty_ships_on_create(attributes)
+ attributes.delete('_reject_me_if_new').present? && new_record?
+ end
+
private
def log_before_add(record)
log(record, "before_adding_method")
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index e1f221bd3e..803c6be53b 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -1,6 +1,7 @@
require 'active_support'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/module/attr_accessor_with_default'
require 'active_support/core_ext/module/delegation'
@@ -162,7 +163,7 @@ module ActiveResource
#
# <tt>404</tt> is just one of the HTTP error response codes that Active Resource will handle with its own exception. The
# following HTTP response codes will also result in these exceptions:
- #
+ #
# * 200..399 - Valid response, no exception (other than 301, 302)
# * 301, 302 - ActiveResource::Redirection
# * 400 - ActiveResource::BadRequest
@@ -421,7 +422,7 @@ module ActiveResource
attr_accessor_with_default(:collection_name) { ActiveSupport::Inflector.pluralize(element_name) } #:nodoc:
attr_accessor_with_default(:primary_key, 'id') #:nodoc:
-
+
# Gets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.xml</tt>)
# This method is regenerated at runtime based on what the \prefix is set to.
def prefix(options={})
@@ -777,7 +778,7 @@ module ActiveResource
# my_other_course = Course.new(:name => "Philosophy: Reason and Being", :lecturer => "Ralph Cling")
# my_other_course.save
def initialize(attributes = {})
- @attributes = {}
+ @attributes = {}.with_indifferent_access
@prefix_options = {}
load(attributes)
end
@@ -922,7 +923,7 @@ module ActiveResource
def save
new? ? create : update
end
-
+
# Saves the resource.
#
# If the resource is new, it is created via +POST+, otherwise the
@@ -931,7 +932,7 @@ module ActiveResource
# With <tt>save!</tt> validations always run. If any of them fail
# ActiveResource::ResourceInvalid gets raised, and nothing is POSTed to
# the remote system.
- # See ActiveResource::Validations for more information.
+ # See ActiveResource::Validations for more information.
#
# There's a series of callbacks associated with <tt>save!</tt>. If any
# of the <tt>before_*</tt> callbacks return +false+ the action is
@@ -1106,6 +1107,36 @@ module ActiveResource
self
end
+ # Updates a single attribute and then saves the object.
+ #
+ # Note: Unlike ActiveRecord::Base.update_attribute, this method <b>is</b>
+ # subject to normal validation routines as an update sends the whole body
+ # of the resource in the request. (See Validations).
+ #
+ # As such, this method is equivalent to calling update_attributes with a single attribute/value pair.
+ #
+ # If the saving fails because of a connection or remote service error, an
+ # exception will be raised. If saving fails because the resource is
+ # invalid then <tt>false</tt> will be returned.
+ def update_attribute(name, value)
+ self.send("#{name}=".to_sym, value)
+ self.save
+ end
+
+ # Updates this resource with all the attributes from the passed-in Hash
+ # and requests that the record be saved.
+ #
+ # If the saving fails because of a connection or remote service error, an
+ # exception will be raised. If saving fails because the resource is
+ # invalid then <tt>false</tt> will be returned.
+ #
+ # Note: Though this request can be made with a partial set of the
+ # resource's attributes, the full body of the request will still be sent
+ # in the save request to the remote service.
+ def update_attributes(attributes)
+ load(attributes) && save
+ end
+
# For checking <tt>respond_to?</tt> without searching the attributes (which is faster).
alias_method :respond_to_without_attributes?, :respond_to?
@@ -1126,7 +1157,6 @@ module ActiveResource
super
end
-
protected
def connection(refresh = false)
self.class.connection(refresh)
diff --git a/activeresource/lib/active_resource/exceptions.rb b/activeresource/lib/active_resource/exceptions.rb
index 0631cdcf9f..0f4549fd73 100644
--- a/activeresource/lib/active_resource/exceptions.rb
+++ b/activeresource/lib/active_resource/exceptions.rb
@@ -8,7 +8,10 @@ module ActiveResource
end
def to_s
- "Failed with #{response.code} #{response.message if response.respond_to?(:message)}"
+ message = "Failed."
+ message << " Response code = #{response.code}." if response.respond_to?(:code)
+ message << " Response message = #{response.message}." if response.respond_to?(:message)
+ message
end
end
diff --git a/activeresource/test/cases/base/load_test.rb b/activeresource/test/cases/base/load_test.rb
index 1952f5b5f0..189a4d81fe 100644
--- a/activeresource/test/cases/base/load_test.rb
+++ b/activeresource/test/cases/base/load_test.rb
@@ -15,26 +15,21 @@ module Highrise
module Deeply
module Nested
-
class Note < ActiveResource::Base
self.site = "http://37s.sunrise.i:3000"
end
- class Comment < ActiveResource::Base
- self.site = "http://37s.sunrise.i:3000"
- end
-
- module TestDifferentLevels
-
- class Note < ActiveResource::Base
- self.site = "http://37s.sunrise.i:3000"
- end
-
- end
+ class Comment < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+ end
+ module TestDifferentLevels
+ class Note < ActiveResource::Base
+ self.site = "http://37s.sunrise.i:3000"
+ end
+ end
end
end
-
end
@@ -68,6 +63,19 @@ class BaseLoadTest < Test::Unit::TestCase
assert_equal @matz.stringify_keys, @person.load(@matz).attributes
end
+ def test_after_load_attributes_are_accessible
+ assert_equal Hash.new, @person.attributes
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
+ assert_equal @matz[:name], @person.attributes['name']
+ end
+
+ def test_after_load_attributes_are_accessible_via_indifferent_access
+ assert_equal Hash.new, @person.attributes
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
+ assert_equal @matz[:name], @person.attributes['name']
+ assert_equal @matz[:name], @person.attributes[:name]
+ end
+
def test_load_one_with_existing_resource
address = @person.load(:street_address => @first_address).street_address
assert_kind_of StreetAddress, address
@@ -143,7 +151,7 @@ class BaseLoadTest < Test::Unit::TestCase
assert_kind_of String, places.first
assert_equal @deep[:street][:state][:places].first, places.first
end
-
+
def test_nested_collections_within_the_same_namespace
n = Highrise::Note.new(:comments => [{ :name => "1" }])
assert_kind_of Highrise::Comment, n.comments.first
@@ -158,6 +166,4 @@ class BaseLoadTest < Test::Unit::TestCase
n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
end
-
-
end
diff --git a/activeresource/test/cases/base_test.rb b/activeresource/test/cases/base_test.rb
index 8c0217aad6..1593e25595 100644
--- a/activeresource/test/cases/base_test.rb
+++ b/activeresource/test/cases/base_test.rb
@@ -11,12 +11,12 @@ class BaseTest < Test::Unit::TestCase
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
@greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
- @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address')
+ @addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
@default_request_headers = { 'Content-Type' => 'application/xml' }
@rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
@people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
@people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
- @addresses = [{ :id => 1, :street => '12345 Street' }].to_xml(:root => 'addresses')
+ @addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')
# - deep nested resource -
# - Luis (Customer)
@@ -102,6 +102,9 @@ class BaseTest < Test::Unit::TestCase
Person.password = nil
end
+ ########################################################################
+ # Tests relating to setting up the API-connection configuration
+ ########################################################################
def test_site_accessor_accepts_uri_or_string_argument
site = URI.parse('http://localhost')
@@ -509,6 +512,11 @@ class BaseTest < Test::Unit::TestCase
assert_not_equal(first_connection, second_connection, 'Connection should be re-created')
end
+
+ ########################################################################
+ # Tests for setting up remote URLs for a given model (including adding
+ # parameters appropriately)
+ ########################################################################
def test_collection_name
assert_equal "people", Person.collection_name
end
@@ -637,6 +645,10 @@ class BaseTest < Test::Unit::TestCase
assert_equal [:person_id].to_set, StreetAddress.__send__(:prefix_parameters)
end
+
+ ########################################################################
+ # Tests basic CRUD functions (find/save/create etc)
+ ########################################################################
def test_respond_to
matz = Person.find(1)
assert matz.respond_to?(:name)
@@ -813,6 +825,55 @@ class BaseTest < Test::Unit::TestCase
assert_raise(ActiveResource::ResourceConflict) { Person.find(2).save }
end
+
+ ######
+ # update_attribute(s)(!)
+
+ def test_update_attribute_as_symbol
+ matz = Person.first
+ matz.expects(:save).returns(true)
+
+ assert_equal "Matz", matz.name
+ assert matz.update_attribute(:name, "David")
+ assert_equal "David", matz.name
+ end
+
+ def test_update_attribute_as_string
+ matz = Person.first
+ matz.expects(:save).returns(true)
+
+ assert_equal "Matz", matz.name
+ assert matz.update_attribute('name', "David")
+ assert_equal "David", matz.name
+ end
+
+
+ def test_update_attributes_as_symbols
+ addy = StreetAddress.first(:params => {:person_id => 1})
+ addy.expects(:save).returns(true)
+
+ assert_equal "12345 Street", addy.street
+ assert_equal "Australia", addy.country
+ assert addy.update_attributes(:street => '54321 Street', :country => 'USA')
+ assert_equal "54321 Street", addy.street
+ assert_equal "USA", addy.country
+ end
+
+ def test_update_attributes_as_strings
+ addy = StreetAddress.first(:params => {:person_id => 1})
+ addy.expects(:save).returns(true)
+
+ assert_equal "12345 Street", addy.street
+ assert_equal "Australia", addy.country
+ assert addy.update_attributes('street' => '54321 Street', 'country' => 'USA')
+ assert_equal "54321 Street", addy.street
+ assert_equal "USA", addy.country
+ end
+
+
+ #####
+ # Mayhem and destruction
+
def test_destroy
assert Person.find(1).destroy
ActiveResource::HttpMock.respond_to do |mock|
@@ -852,7 +913,7 @@ class BaseTest < Test::Unit::TestCase
end
assert_raise(ActiveResource::ResourceNotFound) { StreetAddress.find(1, :params => { :person_id => 1 }) }
end
-
+
def test_delete_with_410_gone
assert Person.delete(1)
ActiveResource::HttpMock.respond_to do |mock|
@@ -861,6 +922,9 @@ class BaseTest < Test::Unit::TestCase
assert_raise(ActiveResource::ResourceGone) { Person.find(1) }
end
+ ########################################################################
+ # Tests the more miscelaneous helper methods
+ ########################################################################
def test_exists
# Class method.
assert !Person.exists?(nil)
diff --git a/activeresource/test/cases/observing_test.rb b/activeresource/test/cases/observing_test.rb
index 9599ff7b0f..925ec7a84a 100644
--- a/activeresource/test/cases/observing_test.rb
+++ b/activeresource/test/cases/observing_test.rb
@@ -10,7 +10,7 @@ class ObservingTest < Test::Unit::TestCase
%w( after_create after_destroy after_save after_update
before_create before_destroy before_save before_update).each do |method|
- define_method(method) { log method }
+ define_method(method) { |*| log method }
end
private
diff --git a/activeresource/test/connection_test.rb b/activeresource/test/connection_test.rb
index d7466c65b4..2a3e04272a 100644
--- a/activeresource/test/connection_test.rb
+++ b/activeresource/test/connection_test.rb
@@ -83,7 +83,7 @@ class ConnectionTest < Test::Unit::TestCase
begin
handle_response ResponseHeaderStub.new(405, "HTTP Failed...", "GET, POST")
rescue ActiveResource::MethodNotAllowed => e
- assert_equal "Failed with 405 HTTP Failed...", e.message
+ assert_equal "Failed. Response code = 405. Response message = HTTP Failed....", e.message
assert_equal [:get, :post], e.allowed_methods
end
end
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index 25f9555388..a415686020 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -115,6 +115,13 @@ module ActiveSupport
self
end
+ def mute
+ previous_silence, @silence = defined?(@silence) && @silence, true
+ yield
+ ensure
+ @silence = previous_silence
+ end
+
# Fetches data from the cache, using the given key. If there is data in
# the cache with the given key, then that data is returned.
#
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index 66ce1bc93a..e6085d97ec 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/duplicable'
+
module ActiveSupport
module Cache
# A cache store implementation which stores everything into memory in the
diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb
index 3b5fccc737..5f6fe22416 100644
--- a/activesupport/lib/active_support/cache/strategy/local_cache.rb
+++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb
@@ -44,7 +44,7 @@ module ActiveSupport
nil
elsif value.nil?
value = super
- local_cache.write(key, value || NULL) if local_cache
+ local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
value.duplicable? ? value.dup : value
else
# forcing the value to be immutable
@@ -54,12 +54,12 @@ module ActiveSupport
def write(key, value, options = nil)
value = value.to_s if respond_to?(:raw?) && raw?(options)
- local_cache.write(key, value || NULL) if local_cache
+ local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
super
end
def delete(key, options = nil)
- local_cache.write(key, NULL) if local_cache
+ local_cache.mute { local_cache.write(key, NULL) } if local_cache
super
end
@@ -76,7 +76,7 @@ module ActiveSupport
def increment(key, amount = 1)
if value = super
- local_cache.write(key, value.to_s) if local_cache
+ local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
value
else
nil
@@ -85,7 +85,7 @@ module ActiveSupport
def decrement(key, amount = 1)
if value = super
- local_cache.write(key, value.to_s) if local_cache
+ local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
value
else
nil
diff --git a/activesupport/lib/active_support/core_ext/string.rb b/activesupport/lib/active_support/core_ext/string.rb
index d06a5a32fb..6c52f12712 100644
--- a/activesupport/lib/active_support/core_ext/string.rb
+++ b/activesupport/lib/active_support/core_ext/string.rb
@@ -7,4 +7,5 @@ require 'active_support/core_ext/string/access'
require 'active_support/core_ext/string/iterators'
require 'active_support/core_ext/string/xchar'
require 'active_support/core_ext/string/behavior'
-require 'active_support/core_ext/string/interpolation' \ No newline at end of file
+require 'active_support/core_ext/string/interpolation'
+require 'active_support/core_ext/string/output_safety' \ No newline at end of file
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
new file mode 100644
index 0000000000..2cca4763f4
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -0,0 +1,43 @@
+class String
+ def html_safe?
+ defined?(@_rails_html_safe) && @_rails_html_safe
+ end
+
+ def html_safe!
+ @_rails_html_safe = true
+ self
+ end
+
+ def html_safe
+ dup.html_safe!
+ end
+
+ alias original_plus +
+ def +(other)
+ result = original_plus(other)
+ if html_safe? && also_html_safe?(other)
+ result.html_safe!
+ else
+ result
+ end
+ end
+
+ alias original_concat <<
+ def <<(other)
+ result = original_concat(other)
+ unless html_safe? && also_html_safe?(other)
+ @_rails_html_safe = false
+ end
+ result
+ end
+
+ def concat(other)
+ self << other
+ end
+
+ private
+ def also_html_safe?(other)
+ other.respond_to?(:html_safe?) && other.html_safe?
+ end
+
+end \ No newline at end of file
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
index 74e080a23d..282346b1a6 100644
--- a/activesupport/lib/active_support/message_verifier.rb
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -26,8 +26,10 @@ module ActiveSupport
end
def verify(signed_message)
+ raise InvalidSignature if signed_message.blank?
+
data, digest = signed_message.split("--")
- if secure_compare(digest, generate_digest(data))
+ if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
Marshal.load(ActiveSupport::Base64.decode64(data))
else
raise InvalidSignature
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index cdd6d5f49b..bec303f6ab 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/load_error'
+
module ActiveSupport
module Testing
class ProxyTestResult
@@ -107,4 +109,4 @@ if ENV['ISOLATION_TEST']
super && test.method_name == ENV['ISOLATION_TEST']
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 7667f11343..892aa97ad7 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -342,3 +342,22 @@ uses_memcached 'memcached backed store' do
include CacheStoreBehavior
end
end
+
+class CacheStoreLoggerTest < ActiveSupport::TestCase
+ def setup
+ @cache = ActiveSupport::Cache.lookup_store(:memory_store)
+
+ @buffer = StringIO.new
+ @cache.logger = Logger.new(@buffer)
+ end
+
+ def test_logging
+ @cache.fetch('foo') { 'bar' }
+ assert @buffer.string.present?
+ end
+
+ def test_mute_logging
+ @cache.mute { @cache.fetch('foo') { 'bar' } }
+ assert @buffer.string.blank?
+ end
+end
diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb
index db9073e298..584a41b631 100644
--- a/activesupport/test/core_ext/string_ext_test.rb
+++ b/activesupport/test/core_ext/string_ext_test.rb
@@ -356,3 +356,89 @@ class StringBytesizeTest < Test::Unit::TestCase
assert_equal 3, 'foo'.bytesize
end
end
+
+class OutputSafetyTest < ActiveSupport::TestCase
+ def setup
+ @string = "hello"
+ end
+
+ test "A string is unsafe by default" do
+ assert !@string.html_safe?
+ end
+
+ test "A string can be marked safe" do
+ @string.html_safe!
+ assert @string.html_safe?
+ end
+
+ test "Marking a string safe returns the string" do
+ assert_equal @string, @string.html_safe!
+ end
+
+ test "Adding a safe string to another safe string returns a safe string" do
+ @other_string = "other".html_safe!
+ @string.html_safe!
+ @combination = @other_string + @string
+
+ assert_equal "otherhello", @combination
+ assert @combination.html_safe?
+ end
+
+ test "Adding an unsafe string to a safe string returns an unsafe string" do
+ @other_string = "other".html_safe!
+ @combination = @other_string + @string
+ @other_combination = @string + @other_string
+
+ assert_equal "otherhello", @combination
+ assert_equal "helloother", @other_combination
+
+ assert !@combination.html_safe?
+ assert !@other_combination.html_safe?
+ end
+
+ test "Concatting safe onto unsafe yields unsafe" do
+ @other_string = "other"
+ @string.html_safe!
+
+ @other_string.concat(@string)
+ assert !@other_string.html_safe?
+ end
+
+ test "Concatting unsafe onto safe yields unsafe" do
+ @other_string = "other".html_safe!
+
+ @other_string.concat(@string)
+ assert !@other_string.html_safe?
+ end
+
+ test "Concatting safe onto safe yields safe" do
+ @other_string = "other".html_safe!
+ @string.html_safe!
+
+ @other_string.concat(@string)
+ assert @other_string.html_safe?
+ end
+
+ test "Concatting safe onto unsafe with << yields unsafe" do
+ @other_string = "other"
+ @string.html_safe!
+
+ @other_string << @string
+ assert !@other_string.html_safe?
+ end
+
+ test "Concatting unsafe onto safe with << yields unsafe" do
+ @other_string = "other".html_safe!
+
+ @other_string << @string
+ assert !@other_string.html_safe?
+ end
+
+ test "Concatting safe onto safe with << yields safe" do
+ @other_string = "other".html_safe!
+ @string.html_safe!
+
+ @other_string << @string
+ assert @other_string.html_safe?
+ end
+end
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index 4f8837ba4e..ef300e4e26 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -18,10 +18,16 @@ class MessageVerifierTest < Test::Unit::TestCase
assert_equal @data, @verifier.verify(message)
end
+ def test_missing_signature_raises
+ assert_not_verified(nil)
+ assert_not_verified("")
+ end
+
def test_tampered_data_raises
data, hash = @verifier.generate(@data).split("--")
assert_not_verified("#{data.reverse}--#{hash}")
assert_not_verified("#{data}--#{hash.reverse}")
+ assert_not_verified("purejunk")
end
def assert_not_verified(message)
diff --git a/ci/ci_build.rb b/ci/ci_build.rb
index fd55444889..b9c321efef 100755
--- a/ci/ci_build.rb
+++ b/ci/ci_build.rb
@@ -66,6 +66,7 @@ cd "#{root_dir}/actionpack" do
puts "[CruiseControl] Building ActionPack"
puts
build_results[:actionpack] = system 'gem bundle && rake'
+ build_results[:actionpack_isolated] = system 'rake test:isolated'
end
cd "#{root_dir}/actionmailer" do
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index 6139e20e95..d54120f850 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -1,29 +1,487 @@
module Rails
class Application
+ extend Initializable
- def self.config
- @config ||= Configuration.new
+ class << self
+ def config
+ @config ||= Configuration.new
+ end
+
+ # TODO: change the plugin loader to use config
+ alias configuration config
+
+ def config=(config)
+ @config = config
+ end
+
+ def plugin_loader
+ @plugin_loader ||= config.plugin_loader.new(self)
+ end
+
+ def routes
+ ActionController::Routing::Routes
+ end
+
+ def middleware
+ config.middleware
+ end
+
+ def call(env)
+ @app ||= middleware.build(routes)
+ @app.call(env)
+ end
+
+ def new
+ initializers.run
+ self
+ end
+ end
+
+ initializer :initialize_rails do
+ Rails.initializers.run
+ end
+
+ # Set the <tt>$LOAD_PATH</tt> based on the value of
+ # Configuration#load_paths. Duplicates are removed.
+ initializer :set_load_path do
+ config.paths.add_to_load_path
+ $LOAD_PATH.uniq!
+ end
+
+ # Bail if boot.rb is outdated
+ initializer :freak_out_if_boot_rb_is_outdated do
+ unless defined?(Rails::BOOTSTRAP_VERSION)
+ abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
+ end
+ end
+
+ # Requires all frameworks specified by the Configuration#frameworks
+ # list. By default, all frameworks (Active Record, Active Support,
+ # Action Pack, Action Mailer, and Active Resource) are loaded.
+ initializer :require_frameworks do
+ begin
+ require 'active_support'
+ require 'active_support/core_ext/kernel/reporting'
+ require 'active_support/core_ext/logger'
+
+ # TODO: This is here to make Sam Ruby's tests pass. Needs discussion.
+ require 'active_support/core_ext/numeric/bytes'
+ config.frameworks.each { |framework| require(framework.to_s) }
+ rescue LoadError => e
+ # Re-raise as RuntimeError because Mongrel would swallow LoadError.
+ raise e.to_s
+ end
+ end
+
+ # Set the paths from which Rails will automatically load source files, and
+ # the load_once paths.
+ initializer :set_autoload_paths do
+ require 'active_support/dependencies'
+ ActiveSupport::Dependencies.load_paths = config.load_paths.uniq
+ ActiveSupport::Dependencies.load_once_paths = config.load_once_paths.uniq
+
+ extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
+ unless extra.empty?
+ abort <<-end_error
+ load_once_paths must be a subset of the load_paths.
+ Extra items in load_once_paths: #{extra * ','}
+ end_error
+ end
+
+ # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
+ config.load_once_paths.freeze
+ end
+
+ # Adds all load paths from plugins to the global set of load paths, so that
+ # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
+ initializer :add_plugin_load_paths do
+ require 'active_support/dependencies'
+ plugin_loader.add_plugin_load_paths
+ end
+
+ # Create tmp directories
+ initializer :ensure_tmp_directories_exist do
+ %w(cache pids sessions sockets).each do |dir_to_make|
+ FileUtils.mkdir_p(File.join(config.root_path, 'tmp', dir_to_make))
+ end
+ end
+
+ # Loads the environment specified by Configuration#environment_path, which
+ # is typically one of development, test, or production.
+ initializer :load_environment do
+ silence_warnings do
+ next if @environment_loaded
+ next unless File.file?(config.environment_path)
+
+ @environment_loaded = true
+ constants = self.class.constants
+
+ eval(IO.read(config.environment_path), binding, config.environment_path)
+
+ (self.class.constants - constants).each do |const|
+ Object.const_set(const, self.class.const_get(const))
+ end
+ end
+ end
+
+ initializer :add_gem_load_paths do
+ require 'rails/gem_dependency'
+ Rails::GemDependency.add_frozen_gem_path
+ unless config.gems.empty?
+ require "rubygems"
+ config.gems.each { |gem| gem.add_load_paths }
+ end
+ end
+
+ # Preload all frameworks specified by the Configuration#frameworks.
+ # Used by Passenger to ensure everything's loaded before forking and
+ # to avoid autoload race conditions in JRuby.
+ initializer :preload_frameworks do
+ if config.preload_frameworks
+ config.frameworks.each do |framework|
+ # String#classify and #constantize aren't available yet.
+ toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
+ toplevel.load_all! if toplevel.respond_to?(:load_all!)
+ end
+ end
+ end
+
+ # This initialization routine does nothing unless <tt>:active_record</tt>
+ # is one of the frameworks to load (Configuration#frameworks). If it is,
+ # this sets the database configuration from Configuration#database_configuration
+ # and then establishes the connection.
+ initializer :initialize_database do
+ if config.frameworks.include?(:active_record)
+ ActiveRecord::Base.configurations = config.database_configuration
+ ActiveRecord::Base.establish_connection
+ end
+ end
+
+ # Include middleware to serve up static assets
+ initializer :initialize_static_server do
+ if config.frameworks.include?(:action_controller) && config.serve_static_assets
+ config.middleware.use(ActionDispatch::Static, Rails.public_path)
+ end
+ end
+
+ initializer :initialize_middleware_stack do
+ if config.frameworks.include?(:action_controller)
+ config.middleware.use(::Rack::Lock) unless ActionController::Base.allow_concurrency
+ config.middleware.use(ActionDispatch::ShowExceptions, ActionController::Base.consider_all_requests_local)
+ config.middleware.use(ActionDispatch::Callbacks, ActionController::Dispatcher.prepare_each_request)
+ config.middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
+ config.middleware.use(ActionDispatch::ParamsParser)
+ config.middleware.use(::Rack::MethodOverride)
+ config.middleware.use(::Rack::Head)
+ config.middleware.use(ActionDispatch::StringCoercion)
+ end
+ end
+
+ initializer :initialize_cache do
+ unless defined?(RAILS_CACHE)
+ silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) }
+
+ if RAILS_CACHE.respond_to?(:middleware)
+ # Insert middleware to setup and teardown local cache for each request
+ config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
+ end
+ end
+ end
+
+ initializer :initialize_framework_caches do
+ if config.frameworks.include?(:action_controller)
+ ActionController::Base.cache_store ||= RAILS_CACHE
+ end
+ end
+
+ initializer :initialize_logger do
+ # if the environment has explicitly defined a logger, use it
+ next if Rails.logger
+
+ unless logger = config.logger
+ begin
+ logger = ActiveSupport::BufferedLogger.new(config.log_path)
+ logger.level = ActiveSupport::BufferedLogger.const_get(config.log_level.to_s.upcase)
+ if RAILS_ENV == "production"
+ logger.auto_flushing = false
+ end
+ rescue StandardError => e
+ logger = ActiveSupport::BufferedLogger.new(STDERR)
+ logger.level = ActiveSupport::BufferedLogger::WARN
+ logger.warn(
+ "Rails Error: Unable to access log file. Please ensure that #{config.log_path} exists and is chmod 0666. " +
+ "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
+ )
+ end
+ end
+
+ # TODO: Why are we silencing warning here?
+ silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
+ end
+
+ # Sets the logger for Active Record, Action Controller, and Action Mailer
+ # (but only for those frameworks that are to be loaded). If the framework's
+ # logger is already set, it is not changed, otherwise it is set to use
+ # RAILS_DEFAULT_LOGGER.
+ initializer :initialize_framework_logging do
+ for framework in ([ :active_record, :action_controller, :action_mailer ] & config.frameworks)
+ framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
+ end
+
+ ActiveSupport::Dependencies.logger ||= Rails.logger
+ Rails.cache.logger ||= Rails.logger
+ end
+
+ # Sets the dependency loading mechanism based on the value of
+ # Configuration#cache_classes.
+ initializer :initialize_dependency_mechanism do
+ # TODO: Remove files from the $" and always use require
+ ActiveSupport::Dependencies.mechanism = config.cache_classes ? :require : :load
+ end
+
+ # Loads support for "whiny nil" (noisy warnings when methods are invoked
+ # on +nil+ values) if Configuration#whiny_nils is true.
+ initializer :initialize_whiny_nils do
+ require('active_support/whiny_nil') if config.whiny_nils
+ end
+
+ # Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
+ # If assigned value cannot be matched to a TimeZone, an exception will be raised.
+ initializer :initialize_time_zone do
+ if config.time_zone
+ zone_default = Time.__send__(:get_zone, config.time_zone)
+
+ unless zone_default
+ raise \
+ 'Value assigned to config.time_zone not recognized.' +
+ 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
+ end
+
+ Time.zone_default = zone_default
+
+ if config.frameworks.include?(:active_record)
+ ActiveRecord::Base.time_zone_aware_attributes = true
+ ActiveRecord::Base.default_timezone = :utc
+ end
+ end
+ end
+
+ # Set the i18n configuration from config.i18n but special-case for the load_path which should be
+ # appended to what's already set instead of overwritten.
+ initializer :initialize_i18n do
+ config.i18n.each do |setting, value|
+ if setting == :load_path
+ I18n.load_path += value
+ else
+ I18n.send("#{setting}=", value)
+ end
+ end
+ end
+
+ # Initializes framework-specific settings for each of the loaded frameworks
+ # (Configuration#frameworks). The available settings map to the accessors
+ # on each of the corresponding Base classes.
+ initializer :initialize_framework_settings do
+ config.frameworks.each do |framework|
+ base_class = framework.to_s.camelize.constantize.const_get("Base")
+
+ config.send(framework).each do |setting, value|
+ base_class.send("#{setting}=", value)
+ end
+ end
+ config.active_support.each do |setting, value|
+ ActiveSupport.send("#{setting}=", value)
+ end
end
- def self.config=(config)
- @config = config
+ # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
+ # (but only for those frameworks that are to be loaded). If the framework's
+ # paths have already been set, it is not changed, otherwise it is
+ # set to use Configuration#view_path.
+ initializer :initialize_framework_views do
+ if config.frameworks.include?(:action_view)
+ view_path = ActionView::PathSet.type_cast(config.view_path, config.cache_classes)
+ ActionMailer::Base.template_root = view_path if config.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
+ ActionController::Base.view_paths = view_path if config.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
+ end
end
- def config
- self.class.config
+ initializer :initialize_metal do
+ # TODO: Make Rails and metal work without ActionController
+ if config.frameworks.include?(:action_controller)
+ Rails::Rack::Metal.requested_metals = config.metals
+ Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
+
+ config.middleware.insert_before(
+ :"ActionDispatch::ParamsParser",
+ Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
+ end
+ end
+
+ initializer :check_for_unbuilt_gems do
+ unbuilt_gems = config.gems.select {|gem| gem.frozen? && !gem.built? }
+ if unbuilt_gems.size > 0
+ # don't print if the gems:build rake tasks are being run
+ unless $gems_build_rake_task
+ abort <<-end_error
+ The following gems have native components that need to be built
+ #{unbuilt_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
+
+ You're running:
+ ruby #{Gem.ruby_version} at #{Gem.ruby}
+ rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
+
+ Run `rake gems:build` to build the unbuilt gems.
+ end_error
+ end
+ end
end
- def routes
- ActionController::Routing::Routes
+ initializer :load_gems do
+ unless $gems_rake_task
+ config.gems.each { |gem| gem.load }
+ end
+ end
+
+ # Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
+ # defaults to <tt>vendor/plugins</tt> but may also be set to a list of
+ # paths, such as
+ # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]
+ #
+ # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized:
+ # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory)
+ # * <tt>init.rb</tt> is evaluated, if present
+ #
+ # After all plugins are loaded, duplicates are removed from the load path.
+ # If an array of plugin names is specified in config.plugins, only those plugins will be loaded
+ # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical
+ # order.
+ #
+ # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other
+ # plugins will be loaded in alphabetical order
+ initializer :load_plugins do
+ plugin_loader.load_plugins
+ end
+
+ # TODO: Figure out if this needs to run a second time
+ # load_gems
+
+ initializer :check_gem_dependencies do
+ unloaded_gems = config.gems.reject { |g| g.loaded? }
+ if unloaded_gems.size > 0
+ configuration.gems_dependencies_loaded = false
+ # don't print if the gems rake tasks are being run
+ unless $gems_rake_task
+ abort <<-end_error
+ Missing these required gems:
+ #{unloaded_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
+
+ You're running:
+ ruby #{Gem.ruby_version} at #{Gem.ruby}
+ rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
+
+ Run `rake gems:install` to install the missing gems.
+ end_error
+ end
+ else
+ configuration.gems_dependencies_loaded = true
+ end
+ end
+
+ # # bail out if gems are missing - note that check_gem_dependencies will have
+ # # already called abort() unless $gems_rake_task is set
+ # return unless gems_dependencies_loaded
+
+ initializer :load_application_initializers do
+ if config.gems_dependencies_loaded
+ Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
+ load(initializer)
+ end
+ end
+ end
+
+ # Fires the user-supplied after_initialize block (Configuration#after_initialize)
+ initializer :after_initialize do
+ if config.gems_dependencies_loaded
+ configuration.after_initialize_blocks.each do |block|
+ block.call
+ end
+ end
+ end
+
+ # # Setup database middleware after initializers have run
+ initializer :initialize_database_middleware do
+ if configuration.frameworks.include?(:active_record)
+ if configuration.frameworks.include?(:action_controller) && ActionController::Base.session_store &&
+ ActionController::Base.session_store.name == 'ActiveRecord::SessionStore'
+ configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
+ configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache
+ else
+ configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
+ configuration.middleware.use ActiveRecord::QueryCache
+ end
+ end
+ end
+
+ # TODO: Make a DSL way to limit an initializer to a particular framework
+
+ # # Prepare dispatcher callbacks and run 'prepare' callbacks
+ initializer :prepare_dispatcher do
+ next unless configuration.frameworks.include?(:action_controller)
+ require 'rails/dispatcher' unless defined?(::Dispatcher)
+ Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
+ end
+
+ # Routing must be initialized after plugins to allow the former to extend the routes
+ # ---
+ # If Action Controller is not one of the loaded frameworks (Configuration#frameworks)
+ # this does nothing. Otherwise, it loads the routing definitions and sets up
+ # loading module used to lazily load controllers (Configuration#controller_paths).
+ initializer :initialize_routing do
+ next unless configuration.frameworks.include?(:action_controller)
+
+ ActionController::Routing.controller_paths += configuration.controller_paths
+ ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
+ ActionController::Routing::Routes.reload!
+ end
+ #
+ # # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
+ initializer :load_observers do
+ if config.gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
+ ActiveRecord::Base.instantiate_observers
+ end
+ end
+
+ # Eager load application classes
+ initializer :load_application_classes do
+ next if $rails_rake_task
+
+ if configuration.cache_classes
+ configuration.eager_load_paths.each do |load_path|
+ matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
+ Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
+ require_dependency file.sub(matcher, '\1')
+ end
+ end
+ end
end
- def middleware
- config.middleware
+ # Disable dependency loading during request cycle
+ initializer :disable_dependency_loading do
+ if configuration.cache_classes && !configuration.dependency_loading
+ ActiveSupport::Dependencies.unhook!
+ end
end
- def call(env)
- @app ||= middleware.build(routes)
- @app.call(env)
+ # Configure generators if they were already loaded
+ # ===
+ # TODO: Does this need to be an initializer here?
+ initializer :initialize_generators do
+ if defined?(Rails::Generators)
+ Rails::Generators.no_color! unless config.generators.colorize_logging
+ Rails::Generators.aliases.deep_merge! config.generators.aliases
+ Rails::Generators.options.deep_merge! config.generators.options
+ end
end
end
end
diff --git a/railties/lib/rails/commands/ncgi/listener b/railties/lib/rails/commands/ncgi/listener
deleted file mode 100755
index 7079ef78a6..0000000000
--- a/railties/lib/rails/commands/ncgi/listener
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'stringio'
-require 'fileutils'
-require 'fcgi_handler'
-
-def message(s)
- $stderr.puts "listener: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
-end
-
-class RemoteCGI < CGI
- attr_accessor :stdinput, :stdoutput, :env_table
- def initialize(env_table, input = nil, output = nil)
- self.env_table = env_table
- self.stdinput = input || StringIO.new
- self.stdoutput = output || StringIO.new
- super()
- end
-
- def out(stream) # Ignore the requested output stream
- super(stdoutput)
- end
-end
-
-class Listener
- include DRbUndumped
-
- def initialize(timeout, socket_path)
- @socket = File.expand_path(socket_path)
- @mutex = Mutex.new
- @active = false
- @timeout = timeout
-
- @handler = RailsFCGIHandler.new
- @handler.extend DRbUndumped
-
- message 'opening socket'
- DRb.start_service("drbunix:#{@socket}", self)
-
- message 'entering process loop'
- @handler.process! self
- end
-
- def each_cgi(&cgi_block)
- @cgi_block = cgi_block
- message 'entering idle loop'
- loop do
- sleep @timeout rescue nil
- die! unless @active
- @active = false
- end
- end
-
- def process(env, input)
- message 'received request'
- @mutex.synchronize do
- @active = true
-
- message 'creating input stream'
- input_stream = StringIO.new(input)
- message 'building CGI instance'
- cgi = RemoteCGI.new(eval(env), input_stream)
-
- message 'yielding to fcgi handler'
- @cgi_block.call cgi
- message 'yield finished -- sending output'
-
- cgi.stdoutput.seek(0)
- output = cgi.stdoutput.read
-
- return output
- end
- end
-
- def die!
- message 'shutting down'
- DRb.stop_service
- FileUtils.rm_f @socket
- Kernel.exit 0
- end
-end
-
-socket_path = ARGV.shift
-timeout = (ARGV.shift || 90).to_i
-
-Listener.new(timeout, socket_path)
diff --git a/railties/lib/rails/core.rb b/railties/lib/rails/core.rb
index 4be90de792..929c38bd22 100644
--- a/railties/lib/rails/core.rb
+++ b/railties/lib/rails/core.rb
@@ -15,11 +15,7 @@ module Rails
# The Configuration instance used to configure the Rails environment
def configuration
- @@configuration
- end
-
- def configuration=(configuration)
- @@configuration = configuration
+ application.configuration
end
def initialized?
diff --git a/railties/lib/rails/fcgi_handler.rb b/railties/lib/rails/fcgi_handler.rb
deleted file mode 100644
index ef6f3b094c..0000000000
--- a/railties/lib/rails/fcgi_handler.rb
+++ /dev/null
@@ -1,239 +0,0 @@
-require 'fcgi'
-require 'logger'
-require 'rails/dispatcher'
-require 'rbconfig'
-
-class RailsFCGIHandler
- SIGNALS = {
- 'HUP' => :reload,
- 'INT' => :exit_now,
- 'TERM' => :exit_now,
- 'USR1' => :exit,
- 'USR2' => :restart
- }
- GLOBAL_SIGNALS = SIGNALS.keys - %w(USR1)
-
- attr_reader :when_ready
-
- attr_accessor :log_file_path
- attr_accessor :gc_request_period
-
- # Initialize and run the FastCGI instance, passing arguments through to new.
- def self.process!(*args, &block)
- new(*args, &block).process!
- end
-
- # Initialize the FastCGI instance with the path to a crash log
- # detailing unhandled exceptions (default RAILS_ROOT/log/fastcgi.crash.log)
- # and the number of requests to process between garbage collection runs
- # (default nil for normal GC behavior.) Optionally, pass a block which
- # takes this instance as an argument for further configuration.
- def initialize(log_file_path = nil, gc_request_period = nil)
- self.log_file_path = log_file_path || "#{RAILS_ROOT}/log/fastcgi.crash.log"
- self.gc_request_period = gc_request_period
-
- # Yield for additional configuration.
- yield self if block_given?
-
- # Safely install signal handlers.
- install_signal_handlers
-
- @app = Dispatcher.new
-
- # Start error timestamp at 11 seconds ago.
- @last_error_on = Time.now - 11
- end
-
- def process!(provider = FCGI)
- mark_features!
-
- dispatcher_log :info, 'starting'
- process_each_request provider
- dispatcher_log :info, 'stopping gracefully'
-
- rescue Exception => error
- case error
- when SystemExit
- dispatcher_log :info, 'stopping after explicit exit'
- when SignalException
- dispatcher_error error, 'stopping after unhandled signal'
- else
- # Retry if exceptions occur more than 10 seconds apart.
- if Time.now - @last_error_on > 10
- @last_error_on = Time.now
- dispatcher_error error, 'retrying after unhandled exception'
- retry
- else
- dispatcher_error error, 'stopping after unhandled exception within 10 seconds of the last'
- end
- end
- end
-
- protected
- def process_each_request(provider)
- request = nil
-
- catch :exit do
- provider.each do |request|
- process_request(request)
-
- case when_ready
- when :reload
- reload!
- when :restart
- close_connection(request)
- restart!
- when :exit
- close_connection(request)
- throw :exit
- end
- end
- end
- rescue SignalException => signal
- raise unless signal.message == 'SIGUSR1'
- close_connection(request)
- end
-
- def process_request(request)
- @processing, @when_ready = true, nil
- gc_countdown
-
- with_signal_handler 'USR1' do
- begin
- ::Rack::Handler::FastCGI.serve(request, @app)
- rescue SignalException, SystemExit
- raise
- rescue Exception => error
- dispatcher_error error, 'unhandled dispatch error'
- end
- end
- ensure
- @processing = false
- end
-
- def logger
- @logger ||= Logger.new(@log_file_path)
- end
-
- def dispatcher_log(level, msg)
- time_str = Time.now.strftime("%d/%b/%Y:%H:%M:%S")
- logger.send(level, "[#{time_str} :: #{$$}] #{msg}")
- rescue Exception => log_error # Logger errors
- STDERR << "Couldn't write to #{@log_file_path.inspect}: #{msg}\n"
- STDERR << " #{log_error.class}: #{log_error.message}\n"
- end
-
- def dispatcher_error(e, msg = "")
- error_message =
- "Dispatcher failed to catch: #{e} (#{e.class})\n" +
- " #{e.backtrace.join("\n ")}\n#{msg}"
- dispatcher_log(:error, error_message)
- end
-
- def install_signal_handlers
- GLOBAL_SIGNALS.each { |signal| install_signal_handler(signal) }
- end
-
- def install_signal_handler(signal, handler = nil)
- if SIGNALS.include?(signal) && self.class.method_defined?(name = "#{SIGNALS[signal]}_handler")
- handler ||= method(name).to_proc
-
- begin
- trap(signal, handler)
- rescue ArgumentError
- dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
- end
- else
- dispatcher_log :warn, "Ignoring unsupported signal #{signal}."
- end
- end
-
- def with_signal_handler(signal)
- install_signal_handler(signal)
- yield
- ensure
- install_signal_handler(signal, 'DEFAULT')
- end
-
- def exit_now_handler(signal)
- dispatcher_log :info, "asked to stop immediately"
- exit
- end
-
- def exit_handler(signal)
- dispatcher_log :info, "asked to stop ASAP"
- if @processing
- @when_ready = :exit
- else
- throw :exit
- end
- end
-
- def reload_handler(signal)
- dispatcher_log :info, "asked to reload ASAP"
- if @processing
- @when_ready = :reload
- else
- reload!
- end
- end
-
- def restart_handler(signal)
- dispatcher_log :info, "asked to restart ASAP"
- if @processing
- @when_ready = :restart
- else
- restart!
- end
- end
-
- def restart!
- config = ::Config::CONFIG
- ruby = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
- command_line = [ruby, $0, ARGV].flatten.join(' ')
-
- dispatcher_log :info, "restarted"
-
- # close resources as they won't be closed by
- # the OS when using exec
- logger.close rescue nil
- Rails.logger.close rescue nil
-
- exec(command_line)
- end
-
- def reload!
- run_gc! if gc_request_period
- restore!
- @when_ready = nil
- dispatcher_log :info, "reloaded"
- end
-
- # Make a note of $" so we can safely reload this instance.
- def mark_features!
- @features = $".clone
- end
-
- def restore!
- $".replace @features
- Dispatcher.reset_application!
- ActionController::Routing::Routes.reload
- end
-
- def run_gc!
- @gc_request_countdown = gc_request_period
- GC.enable; GC.start; GC.disable
- end
-
- def gc_countdown
- if gc_request_period
- @gc_request_countdown ||= gc_request_period
- @gc_request_countdown -= 1
- run_gc! if @gc_request_countdown <= 0
- end
- end
-
- def close_connection(request)
- request.finish if request
- end
-end
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
index 5e6a4af9e0..b5c7fd1e58 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb
@@ -13,7 +13,7 @@
<%% @<%= plural_name %>.each do |<%= singular_name %>| %>
<tr>
<% for attribute in attributes -%>
- <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
+ <td><%%= <%= singular_name %>.<%= attribute.name %> %></td>
<% end -%>
<td><%%= link_to 'Show', <%= singular_name %> %></td>
<td><%%= link_to 'Edit', edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
diff --git a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
index 25567957be..24f13fc0f8 100644
--- a/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
+++ b/railties/lib/rails/generators/erb/scaffold/templates/show.html.erb
@@ -1,7 +1,7 @@
<% for attribute in attributes -%>
<p>
<b><%= attribute.human_name %>:</b>
- <%%=h @<%= singular_name %>.<%= attribute.name %> %>
+ <%%= @<%= singular_name %>.<%= attribute.name %> %>
</p>
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index b2322f90b4..78b4b057ae 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -18,9 +18,6 @@ module Rails::Generators
class_option :template, :type => :string, :aliases => "-m",
:desc => "Path to an application template (can be a filesystem path or URL)."
- class_option :with_dispatchers, :type => :boolean, :aliases => "-D", :default => false,
- :desc => "Add CGI/FastCGI/mod_ruby dispatchers code"
-
class_option :skip_activerecord, :type => :boolean, :aliases => "-O", :default => false,
:desc => "Skip ActiveRecord files"
@@ -113,19 +110,6 @@ module Rails::Generators
directory "public", "public", :recursive => false # Do small steps, so anyone can overwrite it.
end
- def create_dispatch_files
- return unless options[:with_dispatchers]
-
- template "dispatchers/dispatch.rb", "public/dispatch.rb"
- chmod "public/dispatch.rb", 0755, :verbose => false
-
- template "dispatchers/dispatch.rb", "public/dispatch.cgi"
- chmod "public/dispatch.cgi", 0755, :verbose => false
-
- template "dispatchers/dispatch.fcgi", "public/dispatch.fcgi"
- chmod "public/dispatch.fcgi", 0755, :verbose => false
- end
-
def create_public_image_files
directory "public/images"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/boot.rb b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
index 52086fbc7d..6e0e2279cd 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/boot.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/boot.rb
@@ -40,20 +40,20 @@ module Rails
class Boot
def run
- load_initializer
set_load_paths
+ load_initializer
end
def set_load_paths
%w(
- railties
- railties/lib
- activesupport/lib
+ actionmailer/lib
actionpack/lib
+ activemodel/lib
activerecord/lib
- actionmailer/lib
activeresource/lib
- actionwebservice/lib
+ activesupport/lib
+ railties/lib
+ railties
).reverse_each do |path|
path = "#{framework_root_path}/#{path}"
$LOAD_PATH.unshift(path) if File.directory?(path)
@@ -68,7 +68,6 @@ module Rails
class VendorBoot < Boot
def load_initializer
- $:.unshift("#{framework_root_path}/railties/lib")
require "rails"
install_gem_spec_stubs
Rails::GemDependency.add_frozen_gem_path
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi b/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi
deleted file mode 100755
index f5b3b71875..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.fcgi
+++ /dev/null
@@ -1,24 +0,0 @@
-<%= shebang %>
-#
-# You may specify the path to the FastCGI crash log (a log of unhandled
-# exceptions which forced the FastCGI instance to exit, great for debugging)
-# and the number of requests to process before running garbage collection.
-#
-# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
-# and the GC period is nil (turned off). A reasonable number of requests
-# could range from 10-100 depending on the memory footprint of your app.
-#
-# Example:
-# # Default log path, normal GC behavior.
-# RailsFCGIHandler.process!
-#
-# # Default log path, 50 requests between GC.
-# RailsFCGIHandler.process! nil, 50
-#
-# # Custom log path, normal GC behavior.
-# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
-#
-require File.dirname(__FILE__) + "/../config/environment"
-require 'fcgi_handler'
-
-RailsFCGIHandler.process!
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb b/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb
deleted file mode 100755
index 48e888113a..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/dispatch.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-<%= shebang %>
-
-require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
-
-# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
-# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
-require "dispatcher"
-
-ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
-Dispatcher.dispatch
diff --git a/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi b/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi
deleted file mode 100755
index bdc1055a22..0000000000
--- a/railties/lib/rails/generators/rails/app/templates/dispatchers/gateway.cgi
+++ /dev/null
@@ -1,97 +0,0 @@
-<%= shebang %>
-
-require 'drb'
-
-# This file includes an experimental gateway CGI implementation. It will work
-# only on platforms which support both fork and sockets.
-#
-# To enable it edit public/.htaccess and replace dispatch.cgi with gateway.cgi.
-#
-# Next, create the directory log/drb_gateway and grant the apache user rw access
-# to said directory.
-#
-# On the next request to your server, the gateway tracker should start up, along
-# with a few listener processes. This setup should provide you with much better
-# speeds than dispatch.cgi.
-#
-# Keep in mind that the first request made to the server will be slow, as the
-# tracker and listeners will have to load. Also, the tracker and listeners will
-# shutdown after a period if inactivity. You can set this value below -- the
-# default is 90 seconds.
-
-TrackerSocket = File.expand_path(File.join(File.dirname(__FILE__), '../log/drb_gateway/tracker.sock'))
-DieAfter = 90 # Seconds
-Listeners = 3
-
-def message(s)
- $stderr.puts "gateway.cgi: #{s}" if ENV && ENV["DEBUG_GATEWAY"]
-end
-
-def listener_socket(number)
- File.expand_path(File.join(File.dirname(__FILE__), "../log/drb_gateway/listener_#{number}.sock"))
-end
-
-unless File.exist? TrackerSocket
- message "Starting tracker and #{Listeners} listeners"
- fork do
- Process.setsid
- STDIN.reopen "/dev/null"
- STDOUT.reopen "/dev/null", "a"
-
- root = File.expand_path(File.dirname(__FILE__) + '/..')
-
- message "starting tracker"
- fork do
- ARGV.clear
- ARGV << TrackerSocket << Listeners.to_s << DieAfter.to_s
- load File.join(root, 'script', 'tracker')
- end
-
- message "starting listeners"
- require File.join(root, 'config/environment.rb')
- Listeners.times do |number|
- fork do
- ARGV.clear
- ARGV << listener_socket(number) << DieAfter.to_s
- load File.join(root, 'script', 'listener')
- end
- end
- end
-
- message "waiting for tracker and listener to arise..."
- ready = false
- 10.times do
- sleep 0.5
- break if (ready = File.exist?(TrackerSocket) && File.exist?(listener_socket(0)))
- end
-
- if ready
- message "tracker and listener are ready"
- else
- message "Waited 5 seconds, listener and tracker not ready... dropping request"
- Kernel.exit 1
- end
-end
-
-DRb.start_service
-
-message "connecting to tracker"
-tracker = DRbObject.new_with_uri("drbunix:#{TrackerSocket}")
-
-input = $stdin.read
-$stdin.close
-
-env = ENV.inspect
-
-output = nil
-tracker.with_listener do |number|
- message "connecting to listener #{number}"
- socket = listener_socket(number)
- listener = DRbObject.new_with_uri("drbunix:#{socket}")
- output = listener.process(env, input)
- message "listener #{number} has finished, writing output"
-end
-
-$stdout.write output
-$stdout.flush
-$stdout.close
diff --git a/railties/lib/rails/initializable.rb b/railties/lib/rails/initializable.rb
new file mode 100644
index 0000000000..4bd5088207
--- /dev/null
+++ b/railties/lib/rails/initializable.rb
@@ -0,0 +1,99 @@
+module Rails
+ module Initializable
+
+ # A collection of initializers
+ class Collection
+ def initialize(context)
+ @context = context
+ @keys = []
+ @values = {}
+ @ran = false
+ end
+
+ def run
+ return self if @ran
+ each do |key, initializer|
+ @context.class_eval(&initializer.block)
+ end
+ @ran = true
+ self
+ end
+
+ def [](key)
+ keys, values = merge_with_parent
+ values[key.to_sym]
+ end
+
+ def []=(key, value)
+ key = key.to_sym
+ @keys |= [key]
+ @values[key] = value
+ end
+
+ def each
+ keys, values = merge_with_parent
+ keys.each { |k| yield k, values[k] }
+ self
+ end
+
+ protected
+
+ attr_reader :keys, :values
+
+ private
+
+ def merge_with_parent
+ keys, values = [], {}
+
+ if @context.is_a?(Class) && @context.superclass.is_a?(Initializable)
+ parent = @context.superclass.initializers
+ keys, values = parent.keys, parent.values
+ end
+
+ values = values.merge(@values)
+ return keys | @keys, values
+ end
+
+ end
+
+ class Initializer
+ attr_reader :name, :options, :block
+
+ def initialize(name, options = {}, &block)
+ @name, @options, @block = name, options, block
+ end
+ end
+
+ def initializer(name, options = {}, &block)
+ @initializers ||= Collection.new(self)
+ @initializers[name] = Initializer.new(name, options, &block)
+ end
+
+ def initializers
+ @initializers ||= Collection.new(self)
+ end
+
+ end
+
+ extend Initializable
+
+ # Check for valid Ruby version (1.8.2 or 1.8.4 or higher). This is done in an
+ # external file, so we can use it from the `rails` program as well without duplication.
+ initializer :check_ruby_version do
+ require 'rails/ruby_version_check'
+ end
+
+ # For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the
+ # multibyte safe operations. Plugin authors supporting other encodings
+ # should override this behaviour and set the relevant +default_charset+
+ # on ActionController::Base.
+ #
+ # For Ruby 1.9, UTF-8 is the default internal and external encoding.
+ initializer :initialize_encoding do
+ if RUBY_VERSION < '1.9'
+ $KCODE='u'
+ else
+ Encoding.default_external = Encoding::UTF_8
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/lib/rails/initializer.rb b/railties/lib/rails/initializer.rb
index 2d63ac4d39..f7c3774450 100644
--- a/railties/lib/rails/initializer.rb
+++ b/railties/lib/rails/initializer.rb
@@ -1,5 +1,6 @@
require "pathname"
+require 'rails/initializable'
require 'rails/application'
require 'rails/railties_path'
require 'rails/version'
@@ -12,571 +13,16 @@ require 'rails/configuration'
RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
module Rails
- # Sanity check to make sure this file is only loaded once
- # TODO: Get to the point where this can be removed.
- raise "It looks like initializer.rb was required twice" if defined?(Initializer)
-
class Initializer
class Error < StandardError ; end
-
- class Base
- class << self
- def run(&blk)
- define_method(:run, &blk)
- end
-
- def config=(config)
- @@config = config
- end
-
- def config
- @@config || Configuration.new
- end
- alias configuration config
-
- def gems_dependencies_loaded
- config.gems_dependencies_loaded
- end
-
- def plugin_loader
- @plugin_loader ||= configuration.plugin_loader.new(self)
- end
- end
-
- def gems_dependencies_loaded
- self.class.gems_dependencies_loaded
- end
-
- def plugin_loader
- self.class.plugin_loader
- end
- end
-
- class Runner
-
- attr_reader :names, :initializers
- attr_accessor :config
- alias configuration config
-
- def initialize(parent = nil)
- @names = parent ? parent.names.dup : {}
- @initializers = parent ? parent.initializers.dup : []
- end
-
- def add(name, options = {}, &block)
- # If :before or :after is specified, set the index to the right spot
- if other = options[:before] || options[:after]
- raise Error, "The #{other.inspect} initializer does not exist" unless @names[other]
- index = @initializers.index(@names[other])
- index += 1 if options[:after]
- end
-
- @initializers.insert(index || -1, block)
- @names[name] = block
- end
-
- def delete(name)
- @names[name].tap do |initializer|
- @initializers.delete(initializer)
- @names.delete(name)
- end
- end
-
- def run_initializer(initializer)
- init_block = initializer.is_a?(Proc) ? initializer : @names[initializer]
- container = Class.new(Base, &init_block).new
- container.run if container.respond_to?(:run)
- end
-
- def run(initializer = nil)
- Rails.configuration = Base.config = @config
-
- if initializer
- run_initializer(initializer)
- else
- @initializers.each {|block| run_initializer(block) }
- end
- end
- end
-
- def self.default
- @default ||= Runner.new
- end
-
def self.run(initializer = nil, config = nil)
- # TODO: Clean this all up
if initializer
- default.config = config
- default.run(initializer)
+ # Deprecated
else
Rails.application = Class.new(Application)
yield Rails.application.config if block_given?
- default.config = Rails.application.config
- default.run
- end
- end
- end
-
- # Check for valid Ruby version (1.8.2 or 1.8.4 or higher). This is done in an
- # external file, so we can use it from the `rails` program as well without duplication.
- Initializer.default.add :check_ruby_version do
- require 'rails/ruby_version_check'
- end
-
- # Bail if boot.rb is outdated
- Initializer.default.add :freak_out_if_boot_rb_is_outdated do
- unless defined?(Rails::BOOTSTRAP_VERSION)
- abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
- end
- end
-
- # Set the <tt>$LOAD_PATH</tt> based on the value of
- # Configuration#load_paths. Duplicates are removed.
- Initializer.default.add :set_load_path do
- configuration.paths.add_to_load_path
- $LOAD_PATH.uniq!
- end
-
- # Requires all frameworks specified by the Configuration#frameworks
- # list. By default, all frameworks (Active Record, Active Support,
- # Action Pack, Action Mailer, and Active Resource) are loaded.
- Initializer.default.add :require_frameworks do
- begin
- require 'active_support'
- require 'active_support/core_ext/kernel/reporting'
- require 'active_support/core_ext/logger'
-
- # TODO: This is here to make Sam Ruby's tests pass. Needs discussion.
- require 'active_support/core_ext/numeric/bytes'
- configuration.frameworks.each { |framework| require(framework.to_s) }
- rescue LoadError => e
- # Re-raise as RuntimeError because Mongrel would swallow LoadError.
- raise e.to_s
- end
- end
-
- # Set the paths from which Rails will automatically load source files, and
- # the load_once paths.
- Initializer.default.add :set_autoload_paths do
- require 'active_support/dependencies'
- ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
- ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
-
- extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
- unless extra.empty?
- abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
- end_error
- end
-
- # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
- configuration.load_once_paths.freeze
- end
-
- # Adds all load paths from plugins to the global set of load paths, so that
- # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
- Initializer.default.add :add_plugin_load_paths do
- require 'active_support/dependencies'
- plugin_loader.add_plugin_load_paths
- end
-
- # Create tmp directories
- Initializer.default.add :ensure_tmp_directories_exist do
- %w(cache pids sessions sockets).each do |dir_to_make|
- FileUtils.mkdir_p(File.join(configuration.root_path, 'tmp', dir_to_make))
- end
- end
-
- # Loads the environment specified by Configuration#environment_path, which
- # is typically one of development, test, or production.
- Initializer.default.add :load_environment do
- silence_warnings do
- next if @environment_loaded
- next unless File.file?(configuration.environment_path)
-
- @environment_loaded = true
-
- config = configuration
- constants = self.class.constants
-
- eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
-
- (self.class.constants - constants).each do |const|
- Object.const_set(const, self.class.const_get(const))
- end
- end
- end
-
- Initializer.default.add :add_gem_load_paths do
- require 'rails/gem_dependency'
- Rails::GemDependency.add_frozen_gem_path
- unless config.gems.empty?
- require "rubygems"
- config.gems.each { |gem| gem.add_load_paths }
- end
- end
-
- # Preload all frameworks specified by the Configuration#frameworks.
- # Used by Passenger to ensure everything's loaded before forking and
- # to avoid autoload race conditions in JRuby.
- Initializer.default.add :preload_frameworks do
- if configuration.preload_frameworks
- configuration.frameworks.each do |framework|
- # String#classify and #constantize aren't available yet.
- toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
- toplevel.load_all! if toplevel.respond_to?(:load_all!)
- end
- end
- end
-
- # For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the
- # multibyte safe operations. Plugin authors supporting other encodings
- # should override this behaviour and set the relevant +default_charset+
- # on ActionController::Base.
- #
- # For Ruby 1.9, UTF-8 is the default internal and external encoding.
- Initializer.default.add :initialize_encoding do
- if RUBY_VERSION < '1.9'
- $KCODE='u'
- else
- Encoding.default_external = Encoding::UTF_8
- end
- end
-
- # This initialization routine does nothing unless <tt>:active_record</tt>
- # is one of the frameworks to load (Configuration#frameworks). If it is,
- # this sets the database configuration from Configuration#database_configuration
- # and then establishes the connection.
- Initializer.default.add :initialize_database do
- if configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.configurations = configuration.database_configuration
- ActiveRecord::Base.establish_connection
- end
- end
-
- # Include middleware to serve up static assets
- Initializer.default.add :initialize_static_server do
- if configuration.frameworks.include?(:action_controller) && configuration.serve_static_assets
- configuration.middleware.use(ActionDispatch::Static, Rails.public_path)
- end
- end
-
- Initializer.default.add :initialize_middleware_stack do
- if configuration.frameworks.include?(:action_controller)
- configuration.middleware.use(::Rack::Lock) unless ActionController::Base.allow_concurrency
- configuration.middleware.use(ActionDispatch::ShowExceptions, ActionController::Base.consider_all_requests_local)
- configuration.middleware.use(ActionDispatch::Callbacks, ActionController::Dispatcher.prepare_each_request)
- configuration.middleware.use(lambda { ActionController::Base.session_store }, lambda { ActionController::Base.session_options })
- configuration.middleware.use(ActionDispatch::ParamsParser)
- configuration.middleware.use(::Rack::MethodOverride)
- configuration.middleware.use(::Rack::Head)
- end
- end
-
- Initializer.default.add :initialize_cache do
- unless defined?(RAILS_CACHE)
- silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
-
- if RAILS_CACHE.respond_to?(:middleware)
- # Insert middleware to setup and teardown local cache for each request
- configuration.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
- end
- end
- end
-
- Initializer.default.add :initialize_framework_caches do
- if configuration.frameworks.include?(:action_controller)
- ActionController::Base.cache_store ||= RAILS_CACHE
- end
- end
-
- Initializer.default.add :initialize_logger do
- # if the environment has explicitly defined a logger, use it
- next if Rails.logger
-
- unless logger = configuration.logger
- begin
- logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
- logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
- if RAILS_ENV == "production"
- logger.auto_flushing = false
- end
- rescue StandardError => e
- logger = ActiveSupport::BufferedLogger.new(STDERR)
- logger.level = ActiveSupport::BufferedLogger::WARN
- logger.warn(
- "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
- "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
- )
+ Rails.application.new
end
end
-
- # TODO: Why are we silencing warning here?
- silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
- end
-
- # Sets the logger for Active Record, Action Controller, and Action Mailer
- # (but only for those frameworks that are to be loaded). If the framework's
- # logger is already set, it is not changed, otherwise it is set to use
- # RAILS_DEFAULT_LOGGER.
- Initializer.default.add :initialize_framework_logging do
- for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
- framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
- end
-
- ActiveSupport::Dependencies.logger ||= Rails.logger
- Rails.cache.logger ||= Rails.logger
- end
-
- # Sets the dependency loading mechanism based on the value of
- # Configuration#cache_classes.
- Initializer.default.add :initialize_dependency_mechanism do
- # TODO: Remove files from the $" and always use require
- ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
- end
-
- # Loads support for "whiny nil" (noisy warnings when methods are invoked
- # on +nil+ values) if Configuration#whiny_nils is true.
- Initializer.default.add :initialize_whiny_nils do
- require('active_support/whiny_nil') if configuration.whiny_nils
- end
-
-
- # Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
- # If assigned value cannot be matched to a TimeZone, an exception will be raised.
- Initializer.default.add :initialize_time_zone do
- if configuration.time_zone
- zone_default = Time.__send__(:get_zone, configuration.time_zone)
-
- unless zone_default
- raise \
- 'Value assigned to config.time_zone not recognized.' +
- 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
- end
-
- Time.zone_default = zone_default
-
- if configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.time_zone_aware_attributes = true
- ActiveRecord::Base.default_timezone = :utc
- end
- end
- end
-
- # Set the i18n configuration from config.i18n but special-case for the load_path which should be
- # appended to what's already set instead of overwritten.
- Initializer.default.add :initialize_i18n do
- configuration.i18n.each do |setting, value|
- if setting == :load_path
- I18n.load_path += value
- else
- I18n.send("#{setting}=", value)
- end
- end
- end
-
- # Initializes framework-specific settings for each of the loaded frameworks
- # (Configuration#frameworks). The available settings map to the accessors
- # on each of the corresponding Base classes.
- Initializer.default.add :initialize_framework_settings do
- configuration.frameworks.each do |framework|
- base_class = framework.to_s.camelize.constantize.const_get("Base")
-
- configuration.send(framework).each do |setting, value|
- base_class.send("#{setting}=", value)
- end
- end
- configuration.active_support.each do |setting, value|
- ActiveSupport.send("#{setting}=", value)
- end
- end
-
- # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
- # (but only for those frameworks that are to be loaded). If the framework's
- # paths have already been set, it is not changed, otherwise it is
- # set to use Configuration#view_path.
- Initializer.default.add :initialize_framework_views do
- if configuration.frameworks.include?(:action_view)
- view_path = ActionView::PathSet.type_cast(configuration.view_path)
- ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
- ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
- end
- end
-
- Initializer.default.add :initialize_metal do
- # TODO: Make Rails and metal work without ActionController
- if defined?(ActionController)
- Rails::Rack::Metal.requested_metals = configuration.metals
- Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
-
- configuration.middleware.insert_before(
- :"ActionDispatch::ParamsParser",
- Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
- end
- end
-
- Initializer.default.add :check_for_unbuilt_gems do
- unbuilt_gems = config.gems.select {|gem| gem.frozen? && !gem.built? }
- if unbuilt_gems.size > 0
- # don't print if the gems:build rake tasks are being run
- unless $gems_build_rake_task
- abort <<-end_error
-The following gems have native components that need to be built
-#{unbuilt_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
-You're running:
-ruby #{Gem.ruby_version} at #{Gem.ruby}
-rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
-Run `rake gems:build` to build the unbuilt gems.
- end_error
- end
- end
- end
-
- Initializer.default.add :load_gems do
- unless $gems_rake_task
- config.gems.each { |gem| gem.load }
- end
- end
-
- # Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
- # defaults to <tt>vendor/plugins</tt> but may also be set to a list of
- # paths, such as
- # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]
- #
- # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized:
- # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory)
- # * <tt>init.rb</tt> is evaluated, if present
- #
- # After all plugins are loaded, duplicates are removed from the load path.
- # If an array of plugin names is specified in config.plugins, only those plugins will be loaded
- # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical
- # order.
- #
- # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other
- # plugins will be loaded in alphabetical order
- Initializer.default.add :load_plugins do
- plugin_loader.load_plugins
- end
-
- # TODO: Figure out if this needs to run a second time
- # load_gems
-
- Initializer.default.add :check_gem_dependencies do
- unloaded_gems = config.gems.reject { |g| g.loaded? }
- if unloaded_gems.size > 0
- configuration.gems_dependencies_loaded = false
- # don't print if the gems rake tasks are being run
- unless $gems_rake_task
- abort <<-end_error
-Missing these required gems:
-#{unloaded_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
-You're running:
-ruby #{Gem.ruby_version} at #{Gem.ruby}
-rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
-Run `rake gems:install` to install the missing gems.
- end_error
- end
- else
- configuration.gems_dependencies_loaded = true
- end
- end
-
- # # bail out if gems are missing - note that check_gem_dependencies will have
- # # already called abort() unless $gems_rake_task is set
- # return unless gems_dependencies_loaded
-
- Initializer.default.add :load_application_initializers do
- if gems_dependencies_loaded
- Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
- end
- end
- end
-
- # Fires the user-supplied after_initialize block (Configuration#after_initialize)
- Initializer.default.add :after_initialize do
- if gems_dependencies_loaded
- configuration.after_initialize_blocks.each do |block|
- block.call
- end
- end
- end
-
- # # Setup database middleware after initializers have run
- Initializer.default.add :initialize_database_middleware do
- if configuration.frameworks.include?(:active_record)
- if configuration.frameworks.include?(:action_controller) && ActionController::Base.session_store &&
- ActionController::Base.session_store.name == 'ActiveRecord::SessionStore'
- configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
- configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache
- else
- configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
- configuration.middleware.use ActiveRecord::QueryCache
- end
- end
- end
-
- # TODO: Make a DSL way to limit an initializer to a particular framework
-
- # # Prepare dispatcher callbacks and run 'prepare' callbacks
- Initializer.default.add :prepare_dispatcher do
- next unless configuration.frameworks.include?(:action_controller)
- require 'rails/dispatcher' unless defined?(::Dispatcher)
- Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
- end
-
- # Routing must be initialized after plugins to allow the former to extend the routes
- # ---
- # If Action Controller is not one of the loaded frameworks (Configuration#frameworks)
- # this does nothing. Otherwise, it loads the routing definitions and sets up
- # loading module used to lazily load controllers (Configuration#controller_paths).
- Initializer.default.add :initialize_routing do
- next unless configuration.frameworks.include?(:action_controller)
-
- ActionController::Routing.controller_paths += configuration.controller_paths
- ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
- ActionController::Routing::Routes.reload!
- end
- #
- # # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
- Initializer.default.add :load_observers do
- if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.instantiate_observers
- end
- end
-
- # Eager load application classes
- Initializer.default.add :load_application_classes do
- next if $rails_rake_task
-
- if configuration.cache_classes
- configuration.eager_load_paths.each do |load_path|
- matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
- require_dependency file.sub(matcher, '\1')
- end
- end
- end
- end
-
- # Disable dependency loading during request cycle
- Initializer.default.add :disable_dependency_loading do
- if configuration.cache_classes && !configuration.dependency_loading
- ActiveSupport::Dependencies.unhook!
- end
- end
-
- # Configure generators if they were already loaded
- Initializer.default.add :initialize_generators do
- if defined?(Rails::Generators)
- Rails::Generators.no_color! unless config.generators.colorize_logging
- Rails::Generators.aliases.deep_merge! config.generators.aliases
- Rails::Generators.options.deep_merge! config.generators.options
- end
end
end
diff --git a/railties/lib/rails/initializer_old.rb b/railties/lib/rails/initializer_old.rb
deleted file mode 100644
index cee5c7bcb6..0000000000
--- a/railties/lib/rails/initializer_old.rb
+++ /dev/null
@@ -1,1137 +0,0 @@
-require 'logger'
-require 'set'
-require 'pathname'
-
-$LOAD_PATH.unshift File.dirname(__FILE__)
-require 'railties_path'
-require 'rails/version'
-require 'rails/gem_dependency'
-require 'rails/rack'
-
-RAILS_ENV = (ENV['RAILS_ENV'] || 'development').dup unless defined?(RAILS_ENV)
-
-module Rails
- class << self
- # The Configuration instance used to configure the Rails environment
- def configuration
- @@configuration
- end
-
- def configuration=(configuration)
- @@configuration = configuration
- end
-
- def initialized?
- @initialized || false
- end
-
- def initialized=(initialized)
- @initialized ||= initialized
- end
-
- def logger
- if defined?(RAILS_DEFAULT_LOGGER)
- RAILS_DEFAULT_LOGGER
- else
- nil
- end
- end
-
- def backtrace_cleaner
- @@backtrace_cleaner ||= begin
- # Relies on ActiveSupport, so we have to lazy load to postpone definition until AS has been loaded
- require 'rails/backtrace_cleaner'
- Rails::BacktraceCleaner.new
- end
- end
-
- def root
- Pathname.new(RAILS_ROOT) if defined?(RAILS_ROOT)
- end
-
- def env
- @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
- end
-
- def cache
- RAILS_CACHE
- end
-
- def version
- VERSION::STRING
- end
-
- def public_path
- @@public_path ||= self.root ? File.join(self.root, "public") : "public"
- end
-
- def public_path=(path)
- @@public_path = path
- end
- end
-
- # The Initializer is responsible for processing the Rails configuration, such
- # as setting the $LOAD_PATH, requiring the right frameworks, initializing
- # logging, and more. It can be run either as a single command that'll just
- # use the default configuration, like this:
- #
- # Rails::Initializer.run
- #
- # But normally it's more interesting to pass in a custom configuration
- # through the block running:
- #
- # Rails::Initializer.run do |config|
- # config.frameworks -= [ :action_mailer ]
- # end
- #
- # This will use the default configuration options from Rails::Configuration,
- # but allow for overwriting on select areas.
- class Initializer
- # The Configuration instance used by this Initializer instance.
- attr_reader :configuration
-
- # The set of loaded plugins.
- attr_reader :loaded_plugins
-
- # Whether or not all the gem dependencies have been met
- attr_reader :gems_dependencies_loaded
-
- # Runs the initializer. By default, this will invoke the #process method,
- # which simply executes all of the initialization routines. Alternately,
- # you can specify explicitly which initialization routine you want:
- #
- # Rails::Initializer.run(:set_load_path)
- #
- # This is useful if you only want the load path initialized, without
- # incurring the overhead of completely loading the entire environment.
- def self.run(command = :process, configuration = Configuration.new)
- yield configuration if block_given?
- initializer = new configuration
- initializer.send(command)
- initializer
- end
-
- # Create a new Initializer instance that references the given Configuration
- # instance.
- def initialize(configuration)
- @configuration = configuration
- @loaded_plugins = []
- end
-
- # Sequentially step through all of the available initialization routines,
- # in order (view execution order in source).
- def process
- Rails.configuration = configuration
-
- check_ruby_version
- install_gem_spec_stubs
- set_load_path
- add_gem_load_paths
-
- require_frameworks
- set_autoload_paths
- add_plugin_load_paths
- load_environment
- preload_frameworks
-
- initialize_encoding
- initialize_database
-
- initialize_cache
- initialize_framework_caches
-
- initialize_logger
- initialize_framework_logging
-
- initialize_dependency_mechanism
- initialize_whiny_nils
-
- initialize_time_zone
- initialize_i18n
-
- initialize_framework_settings
- initialize_framework_views
-
- initialize_metal
-
- add_support_load_paths
-
- check_for_unbuilt_gems
-
- load_gems
- load_plugins
-
- # pick up any gems that plugins depend on
- add_gem_load_paths
- load_gems
- check_gem_dependencies
-
- # bail out if gems are missing - note that check_gem_dependencies will have
- # already called abort() unless $gems_rake_task is set
- return unless gems_dependencies_loaded
-
- load_application_initializers
-
- # the framework is now fully initialized
- after_initialize
-
- # Setup database middleware after initializers have run
- initialize_database_middleware
-
- # Prepare dispatcher callbacks and run 'prepare' callbacks
- prepare_dispatcher
-
- # Routing must be initialized after plugins to allow the former to extend the routes
- initialize_routing
-
- # Observers are loaded after plugins in case Observers or observed models are modified by plugins.
- load_observers
-
- # Load view path cache
- load_view_paths
-
- # Load application classes
- load_application_classes
-
- # Disable dependency loading during request cycle
- disable_dependency_loading
-
- # Flag initialized
- Rails.initialized = true
- end
-
- # Check for valid Ruby version
- # This is done in an external file, so we can use it
- # from the `rails` program as well without duplication.
- def check_ruby_version
- require 'ruby_version_check'
- end
-
- # If Rails is vendored and RubyGems is available, install stub GemSpecs
- # for Rails, Active Support, Active Record, Action Pack, Action Mailer, and
- # Active Resource. This allows Gem plugins to depend on Rails even when
- # the Gem version of Rails shouldn't be loaded.
- def install_gem_spec_stubs
- unless Rails.respond_to?(:vendor_rails?)
- abort %{Your config/boot.rb is outdated: Run "rake rails:update".}
- end
-
- if Rails.vendor_rails?
- begin; require "rubygems"; rescue LoadError; return; end
-
- stubs = %w(rails activesupport activerecord actionpack actionmailer activeresource)
- stubs.reject! { |s| Gem.loaded_specs.key?(s) }
-
- stubs.each do |stub|
- Gem.loaded_specs[stub] = Gem::Specification.new do |s|
- s.name = stub
- s.version = Rails::VERSION::STRING
- s.loaded_from = ""
- end
- end
- end
- end
-
- # Set the <tt>$LOAD_PATH</tt> based on the value of
- # Configuration#load_paths. Duplicates are removed.
- def set_load_path
- load_paths = configuration.load_paths + configuration.framework_paths
- load_paths.reverse_each { |dir| $LOAD_PATH.unshift(dir) if File.directory?(dir) }
- $LOAD_PATH.uniq!
- end
-
- # Set the paths from which Rails will automatically load source files, and
- # the load_once paths.
- def set_autoload_paths
- require 'active_support/dependencies'
- ActiveSupport::Dependencies.load_paths = configuration.load_paths.uniq
- ActiveSupport::Dependencies.load_once_paths = configuration.load_once_paths.uniq
-
- extra = ActiveSupport::Dependencies.load_once_paths - ActiveSupport::Dependencies.load_paths
- unless extra.empty?
- abort <<-end_error
- load_once_paths must be a subset of the load_paths.
- Extra items in load_once_paths: #{extra * ','}
- end_error
- end
-
- # Freeze the arrays so future modifications will fail rather than do nothing mysteriously
- configuration.load_once_paths.freeze
- end
-
- # Requires all frameworks specified by the Configuration#frameworks
- # list. By default, all frameworks (Active Record, Active Support,
- # Action Pack, Action Mailer, and Active Resource) are loaded.
- def require_frameworks
- require 'active_support/all'
- configuration.frameworks.each { |framework| require(framework.to_s) }
- rescue LoadError => e
- # Re-raise as RuntimeError because Mongrel would swallow LoadError.
- raise e.to_s
- end
-
- # Preload all frameworks specified by the Configuration#frameworks.
- # Used by Passenger to ensure everything's loaded before forking and
- # to avoid autoload race conditions in JRuby.
- def preload_frameworks
- if configuration.preload_frameworks
- configuration.frameworks.each do |framework|
- # String#classify and #constantize aren't available yet.
- toplevel = Object.const_get(framework.to_s.gsub(/(?:^|_)(.)/) { $1.upcase })
- toplevel.load_all! if toplevel.respond_to?(:load_all!)
- end
- end
- end
-
- # Add the load paths used by support functions such as the info controller
- def add_support_load_paths
- end
-
- # Adds all load paths from plugins to the global set of load paths, so that
- # code from plugins can be required (explicitly or automatically via ActiveSupport::Dependencies).
- def add_plugin_load_paths
- require 'active_support/dependencies'
- plugin_loader.add_plugin_load_paths
- end
-
- def add_gem_load_paths
- require 'rails/gem_dependency'
- Rails::GemDependency.add_frozen_gem_path
- unless @configuration.gems.empty?
- require "rubygems"
- @configuration.gems.each { |gem| gem.add_load_paths }
- end
- end
-
- def load_gems
- unless $gems_rake_task
- @configuration.gems.each { |gem| gem.load }
- end
- end
-
- def check_for_unbuilt_gems
- unbuilt_gems = @configuration.gems.select {|gem| gem.frozen? && !gem.built? }
- if unbuilt_gems.size > 0
- # don't print if the gems:build rake tasks are being run
- unless $gems_build_rake_task
- abort <<-end_error
-The following gems have native components that need to be built
- #{unbuilt_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
-You're running:
- ruby #{Gem.ruby_version} at #{Gem.ruby}
- rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
-Run `rake gems:build` to build the unbuilt gems.
- end_error
- end
- end
- end
-
- def check_gem_dependencies
- unloaded_gems = @configuration.gems.reject { |g| g.loaded? }
- if unloaded_gems.size > 0
- @gems_dependencies_loaded = false
- # don't print if the gems rake tasks are being run
- unless $gems_rake_task
- abort <<-end_error
-Missing these required gems:
- #{unloaded_gems.map { |gemm| "#{gemm.name} #{gemm.requirement}" } * "\n "}
-
-You're running:
- ruby #{Gem.ruby_version} at #{Gem.ruby}
- rubygems #{Gem::RubyGemsVersion} at #{Gem.path * ', '}
-
-Run `rake gems:install` to install the missing gems.
- end_error
- end
- else
- @gems_dependencies_loaded = true
- end
- end
-
- # Loads all plugins in <tt>config.plugin_paths</tt>. <tt>plugin_paths</tt>
- # defaults to <tt>vendor/plugins</tt> but may also be set to a list of
- # paths, such as
- # config.plugin_paths = ["#{RAILS_ROOT}/lib/plugins", "#{RAILS_ROOT}/vendor/plugins"]
- #
- # In the default implementation, as each plugin discovered in <tt>plugin_paths</tt> is initialized:
- # * its +lib+ directory, if present, is added to the load path (immediately after the applications lib directory)
- # * <tt>init.rb</tt> is evaluated, if present
- #
- # After all plugins are loaded, duplicates are removed from the load path.
- # If an array of plugin names is specified in config.plugins, only those plugins will be loaded
- # and they plugins will be loaded in that order. Otherwise, plugins are loaded in alphabetical
- # order.
- #
- # if config.plugins ends contains :all then the named plugins will be loaded in the given order and all other
- # plugins will be loaded in alphabetical order
- def load_plugins
- plugin_loader.load_plugins
- end
-
- def plugin_loader
- @plugin_loader ||= configuration.plugin_loader.new(self)
- end
-
- # Loads the environment specified by Configuration#environment_path, which
- # is typically one of development, test, or production.
- def load_environment
- silence_warnings do
- return if @environment_loaded
- @environment_loaded = true
-
- config = configuration
- constants = self.class.constants
-
- eval(IO.read(configuration.environment_path), binding, configuration.environment_path)
-
- (self.class.constants - constants).each do |const|
- Object.const_set(const, self.class.const_get(const))
- end
- end
- end
-
- def load_observers
- if gems_dependencies_loaded && configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.instantiate_observers
- end
- end
-
- def load_view_paths
- if configuration.frameworks.include?(:action_view)
- if configuration.cache_classes
- view_path = ActionView::FileSystemResolverWithFallback.new(configuration.view_path)
- ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller)
- ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer)
- end
- end
- end
-
- # Eager load application classes
- def load_application_classes
- return if $rails_rake_task
- if configuration.cache_classes
- configuration.eager_load_paths.each do |load_path|
- matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/
- Dir.glob("#{load_path}/**/*.rb").sort.each do |file|
- require_dependency file.sub(matcher, '\1')
- end
- end
- end
- end
-
- # For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the
- # multibyte safe operations. Plugin authors supporting other encodings
- # should override this behaviour and set the relevant +default_charset+
- # on ActionController::Base.
- #
- # For Ruby 1.9, UTF-8 is the default internal and external encoding.
- def initialize_encoding
- if RUBY_VERSION < '1.9'
- $KCODE='u'
- else
- Encoding.default_internal = Encoding::UTF_8
- Encoding.default_external = Encoding::UTF_8
- end
- end
-
- # This initialization routine does nothing unless <tt>:active_record</tt>
- # is one of the frameworks to load (Configuration#frameworks). If it is,
- # this sets the database configuration from Configuration#database_configuration
- # and then establishes the connection.
- def initialize_database
- if configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.configurations = configuration.database_configuration
- ActiveRecord::Base.establish_connection
- end
- end
-
- def initialize_database_middleware
- if configuration.frameworks.include?(:active_record)
- if configuration.frameworks.include?(:action_controller) &&
- ActionController::Base.session_store.name == 'ActiveRecord::SessionStore'
- configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement
- configuration.middleware.insert_before :"ActiveRecord::SessionStore", ActiveRecord::QueryCache
- else
- configuration.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
- configuration.middleware.use ActiveRecord::QueryCache
- end
- end
- end
-
- def initialize_cache
- unless defined?(RAILS_CACHE)
- silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
-
- if RAILS_CACHE.respond_to?(:middleware)
- # Insert middleware to setup and teardown local cache for each request
- configuration.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
- end
- end
- end
-
- def initialize_framework_caches
- if configuration.frameworks.include?(:action_controller)
- ActionController::Base.cache_store ||= RAILS_CACHE
- end
- end
-
- # If the RAILS_DEFAULT_LOGGER constant is already set, this initialization
- # routine does nothing. If the constant is not set, and Configuration#logger
- # is not +nil+, this also does nothing. Otherwise, a new logger instance
- # is created at Configuration#log_path, with a default log level of
- # Configuration#log_level.
- #
- # If the log could not be created, the log will be set to output to
- # +STDERR+, with a log level of +WARN+.
- def initialize_logger
- # if the environment has explicitly defined a logger, use it
- return if Rails.logger
-
- unless logger = configuration.logger
- begin
- logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
- logger.level = ActiveSupport::BufferedLogger.const_get(configuration.log_level.to_s.upcase)
- if configuration.environment == "production"
- logger.auto_flushing = false
- end
- rescue StandardError => e
- logger = ActiveSupport::BufferedLogger.new(STDERR)
- logger.level = ActiveSupport::BufferedLogger::WARN
- logger.warn(
- "Rails Error: Unable to access log file. Please ensure that #{configuration.log_path} exists and is chmod 0666. " +
- "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
- )
- end
- end
-
- silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }
- end
-
- # Sets the logger for Active Record, Action Controller, and Action Mailer
- # (but only for those frameworks that are to be loaded). If the framework's
- # logger is already set, it is not changed, otherwise it is set to use
- # RAILS_DEFAULT_LOGGER.
- def initialize_framework_logging
- for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks)
- framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger
- end
-
- ActiveSupport::Dependencies.logger ||= Rails.logger
- Rails.cache.logger ||= Rails.logger
- end
-
- # Sets +ActionController::Base#view_paths+ and +ActionMailer::Base#template_root+
- # (but only for those frameworks that are to be loaded). If the framework's
- # paths have already been set, it is not changed, otherwise it is
- # set to use Configuration#view_path.
- def initialize_framework_views
- if configuration.frameworks.include?(:action_view)
- view_path = ActionView::PathSet.type_cast(configuration.view_path)
- ActionMailer::Base.template_root = view_path if configuration.frameworks.include?(:action_mailer) && ActionMailer::Base.view_paths.blank?
- ActionController::Base.view_paths = view_path if configuration.frameworks.include?(:action_controller) && ActionController::Base.view_paths.blank?
- end
- end
-
- # If Action Controller is not one of the loaded frameworks (Configuration#frameworks)
- # this does nothing. Otherwise, it loads the routing definitions and sets up
- # loading module used to lazily load controllers (Configuration#controller_paths).
- def initialize_routing
- return unless configuration.frameworks.include?(:action_controller)
-
- ActionController::Routing.controller_paths += configuration.controller_paths
- ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file)
- ActionController::Routing::Routes.reload!
- end
-
- # Sets the dependency loading mechanism based on the value of
- # Configuration#cache_classes.
- def initialize_dependency_mechanism
- ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load
- end
-
- # Loads support for "whiny nil" (noisy warnings when methods are invoked
- # on +nil+ values) if Configuration#whiny_nils is true.
- def initialize_whiny_nils
- require('active_support/whiny_nil') if configuration.whiny_nils
- end
-
- # Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
- # If assigned value cannot be matched to a TimeZone, an exception will be raised.
- def initialize_time_zone
- if configuration.time_zone
- zone_default = Time.__send__(:get_zone, configuration.time_zone)
-
- unless zone_default
- raise \
- 'Value assigned to config.time_zone not recognized.' +
- 'Run "rake -D time" for a list of tasks for finding appropriate time zone names.'
- end
-
- Time.zone_default = zone_default
-
- if configuration.frameworks.include?(:active_record)
- ActiveRecord::Base.time_zone_aware_attributes = true
- ActiveRecord::Base.default_timezone = :utc
- end
- end
- end
-
- # Set the i18n configuration from config.i18n but special-case for the load_path which should be
- # appended to what's already set instead of overwritten.
- def initialize_i18n
- configuration.i18n.each do |setting, value|
- if setting == :load_path
- I18n.load_path += value
- else
- I18n.send("#{setting}=", value)
- end
- end
- end
-
- def initialize_metal
- Rails::Rack::Metal.requested_metals = configuration.metals
- Rails::Rack::Metal.metal_paths += plugin_loader.engine_metal_paths
-
- configuration.middleware.insert_before(
- :"ActionDispatch::ParamsParser",
- Rails::Rack::Metal, :if => Rails::Rack::Metal.metals.any?)
- end
-
- # Initializes framework-specific settings for each of the loaded frameworks
- # (Configuration#frameworks). The available settings map to the accessors
- # on each of the corresponding Base classes.
- def initialize_framework_settings
- configuration.frameworks.each do |framework|
- base_class = framework.to_s.camelize.constantize.const_get("Base")
-
- configuration.send(framework).each do |setting, value|
- base_class.send("#{setting}=", value)
- end
- end
- configuration.active_support.each do |setting, value|
- ActiveSupport.send("#{setting}=", value)
- end
- end
-
- # Fires the user-supplied after_initialize block (Configuration#after_initialize)
- def after_initialize
- if gems_dependencies_loaded
- configuration.after_initialize_blocks.each do |block|
- block.call
- end
- end
- end
-
- def load_application_initializers
- if gems_dependencies_loaded
- Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer|
- load(initializer)
- end
- end
- end
-
- def prepare_dispatcher
- return unless configuration.frameworks.include?(:action_controller)
- require 'dispatcher' unless defined?(::Dispatcher)
- Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
- end
-
- def disable_dependency_loading
- if configuration.cache_classes && !configuration.dependency_loading
- ActiveSupport::Dependencies.unhook!
- end
- end
- end
-
- # The Configuration class holds all the parameters for the Initializer and
- # ships with defaults that suites most Rails applications. But it's possible
- # to overwrite everything. Usually, you'll create an Configuration file
- # implicitly through the block running on the Initializer, but it's also
- # possible to create the Configuration instance in advance and pass it in
- # like this:
- #
- # config = Rails::Configuration.new
- # Rails::Initializer.run(:process, config)
- class Configuration
- # The application's base directory.
- attr_reader :root_path
-
- # A stub for setting options on ActionController::Base.
- attr_accessor :action_controller
-
- # A stub for setting options on ActionMailer::Base.
- attr_accessor :action_mailer
-
- # A stub for setting options on ActionView::Base.
- attr_accessor :action_view
-
- # A stub for setting options on ActiveRecord::Base.
- attr_accessor :active_record
-
- # A stub for setting options on ActiveResource::Base.
- attr_accessor :active_resource
-
- # A stub for setting options on ActiveSupport.
- attr_accessor :active_support
-
- # Whether to preload all frameworks at startup.
- attr_accessor :preload_frameworks
-
- # Whether or not classes should be cached (set to false if you want
- # application classes to be reloaded on each request)
- attr_accessor :cache_classes
-
- # The list of paths that should be searched for controllers. (Defaults
- # to <tt>app/controllers</tt>.)
- attr_accessor :controller_paths
-
- # The path to the database configuration file to use. (Defaults to
- # <tt>config/database.yml</tt>.)
- attr_accessor :database_configuration_file
-
- # The path to the routes configuration file to use. (Defaults to
- # <tt>config/routes.rb</tt>.)
- attr_accessor :routes_configuration_file
-
- # The list of rails framework components that should be loaded. (Defaults
- # to <tt>:active_record</tt>, <tt>:action_controller</tt>,
- # <tt>:action_view</tt>, <tt>:action_mailer</tt>, and
- # <tt>:active_resource</tt>).
- attr_accessor :frameworks
-
- # An array of additional paths to prepend to the load path. By default,
- # all +app+, +lib+, +vendor+ and mock paths are included in this list.
- attr_accessor :load_paths
-
- # An array of paths from which Rails will automatically load from only once.
- # All elements of this array must also be in +load_paths+.
- attr_accessor :load_once_paths
-
- # An array of paths from which Rails will eager load on boot if cache
- # classes is enabled. All elements of this array must also be in
- # +load_paths+.
- attr_accessor :eager_load_paths
-
- # The log level to use for the default Rails logger. In production mode,
- # this defaults to <tt>:info</tt>. In development mode, it defaults to
- # <tt>:debug</tt>.
- attr_accessor :log_level
-
- # The path to the log file to use. Defaults to log/#{environment}.log
- # (e.g. log/development.log or log/production.log).
- attr_accessor :log_path
-
- # The specific logger to use. By default, a logger will be created and
- # initialized using #log_path and #log_level, but a programmer may
- # specifically set the logger to use via this accessor and it will be
- # used directly.
- attr_accessor :logger
-
- # The specific cache store to use. By default, the ActiveSupport::Cache::Store will be used.
- attr_accessor :cache_store
-
- # The root of the application's views. (Defaults to <tt>app/views</tt>.)
- attr_accessor :view_path
-
- # Set to +true+ if you want to be warned (noisily) when you try to invoke
- # any method of +nil+. Set to +false+ for the standard Ruby behavior.
- attr_accessor :whiny_nils
-
- # The list of plugins to load. If this is set to <tt>nil</tt>, all plugins will
- # be loaded. If this is set to <tt>[]</tt>, no plugins will be loaded. Otherwise,
- # plugins will be loaded in the order specified.
- attr_reader :plugins
- def plugins=(plugins)
- @plugins = plugins.nil? ? nil : plugins.map { |p| p.to_sym }
- end
-
- # The list of metals to load. If this is set to <tt>nil</tt>, all metals will
- # be loaded in alphabetical order. If this is set to <tt>[]</tt>, no metals will
- # be loaded. Otherwise metals will be loaded in the order specified
- attr_accessor :metals
-
- # The path to the root of the plugins directory. By default, it is in
- # <tt>vendor/plugins</tt>.
- attr_accessor :plugin_paths
-
- # The classes that handle finding the desired plugins that you'd like to load for
- # your application. By default it is the Rails::Plugin::FileSystemLocator which finds
- # plugins to load in <tt>vendor/plugins</tt>. You can hook into gem location by subclassing
- # Rails::Plugin::Locator and adding it onto the list of <tt>plugin_locators</tt>.
- attr_accessor :plugin_locators
-
- # The class that handles loading each plugin. Defaults to Rails::Plugin::Loader, but
- # a sub class would have access to fine grained modification of the loading behavior. See
- # the implementation of Rails::Plugin::Loader for more details.
- attr_accessor :plugin_loader
-
- # Enables or disables plugin reloading. You can get around this setting per plugin.
- # If <tt>reload_plugins?</tt> is false, add this to your plugin's <tt>init.rb</tt>
- # to make it reloadable:
- #
- # ActiveSupport::Dependencies.load_once_paths.delete lib_path
- #
- # If <tt>reload_plugins?</tt> is true, add this to your plugin's <tt>init.rb</tt>
- # to only load it once:
- #
- # ActiveSupport::Dependencies.load_once_paths << lib_path
- #
- attr_accessor :reload_plugins
-
- # Returns true if plugin reloading is enabled.
- def reload_plugins?
- !!@reload_plugins
- end
-
- # Enables or disables dependency loading during the request cycle. Setting
- # <tt>dependency_loading</tt> to true will allow new classes to be loaded
- # during a request. Setting it to false will disable this behavior.
- #
- # Those who want to run in a threaded environment should disable this
- # option and eager load or require all there classes on initialization.
- #
- # If <tt>cache_classes</tt> is disabled, dependency loaded will always be
- # on.
- attr_accessor :dependency_loading
-
- # An array of gems that this rails application depends on. Rails will automatically load
- # these gems during installation, and allow you to install any missing gems with:
- #
- # rake gems:install
- #
- # You can add gems with the #gem method.
- attr_accessor :gems
-
- # Adds a single Gem dependency to the rails application. By default, it will require
- # the library with the same name as the gem. Use :lib to specify a different name.
- #
- # # gem 'aws-s3', '>= 0.4.0'
- # # require 'aws/s3'
- # config.gem 'aws-s3', :lib => 'aws/s3', :version => '>= 0.4.0', \
- # :source => "http://code.whytheluckystiff.net"
- #
- # To require a library be installed, but not attempt to load it, pass :lib => false
- #
- # config.gem 'qrp', :version => '0.4.1', :lib => false
- def gem(name, options = {})
- @gems << Rails::GemDependency.new(name, options)
- end
-
- # Deprecated options:
- def breakpoint_server(_ = nil)
- $stderr.puts %(
- *******************************************************************
- * config.breakpoint_server has been deprecated and has no effect. *
- *******************************************************************
- )
- end
- alias_method :breakpoint_server=, :breakpoint_server
-
- # Sets the default +time_zone+. Setting this will enable +time_zone+
- # awareness for Active Record models and set the Active Record default
- # timezone to <tt>:utc</tt>.
- attr_accessor :time_zone
-
- # Accessor for i18n settings.
- attr_accessor :i18n
-
- # Create a new Configuration instance, initialized with the default
- # values.
- def initialize
- set_root_path!
-
- self.frameworks = default_frameworks
- self.load_paths = default_load_paths
- self.load_once_paths = default_load_once_paths
- self.eager_load_paths = default_eager_load_paths
- self.log_path = default_log_path
- self.log_level = default_log_level
- self.view_path = default_view_path
- self.controller_paths = default_controller_paths
- self.preload_frameworks = default_preload_frameworks
- self.cache_classes = default_cache_classes
- self.dependency_loading = default_dependency_loading
- self.whiny_nils = default_whiny_nils
- self.plugins = default_plugins
- self.plugin_paths = default_plugin_paths
- self.plugin_locators = default_plugin_locators
- self.plugin_loader = default_plugin_loader
- self.database_configuration_file = default_database_configuration_file
- self.routes_configuration_file = default_routes_configuration_file
- self.gems = default_gems
- self.i18n = default_i18n
-
- for framework in default_frameworks
- self.send("#{framework}=", Rails::OrderedOptions.new)
- end
- self.active_support = Rails::OrderedOptions.new
- end
-
- # Set the root_path to RAILS_ROOT and canonicalize it.
- def set_root_path!
- raise 'RAILS_ROOT is not set' unless defined?(::RAILS_ROOT)
- raise 'RAILS_ROOT is not a directory' unless File.directory?(::RAILS_ROOT)
-
- @root_path =
- # Pathname is incompatible with Windows, but Windows doesn't have
- # real symlinks so File.expand_path is safe.
- if RUBY_PLATFORM =~ /(:?mswin|mingw)/
- File.expand_path(::RAILS_ROOT)
-
- # Otherwise use Pathname#realpath which respects symlinks.
- else
- Pathname.new(::RAILS_ROOT).realpath.to_s
- end
-
- Object.const_set(:RELATIVE_RAILS_ROOT, ::RAILS_ROOT.dup) unless defined?(::RELATIVE_RAILS_ROOT)
- ::RAILS_ROOT.replace @root_path
- end
-
- # Enable threaded mode. Allows concurrent requests to controller actions and
- # multiple database connections. Also disables automatic dependency loading
- # after boot, and disables reloading code on every request, as these are
- # fundamentally incompatible with thread safety.
- def threadsafe!
- self.preload_frameworks = true
- self.cache_classes = true
- self.dependency_loading = false
- self.action_controller.allow_concurrency = true
- self
- end
-
- # Loads and returns the contents of the #database_configuration_file. The
- # contents of the file are processed via ERB before being sent through
- # YAML::load.
- def database_configuration
- require 'erb'
- YAML::load(ERB.new(IO.read(database_configuration_file)).result)
- end
-
- # The path to the current environment's file (<tt>development.rb</tt>, etc.). By
- # default the file is at <tt>config/environments/#{environment}.rb</tt>.
- def environment_path
- "#{root_path}/config/environments/#{environment}.rb"
- end
-
- # Return the currently selected environment. By default, it returns the
- # value of the RAILS_ENV constant.
- def environment
- ::RAILS_ENV
- end
-
- # Adds a block which will be executed after rails has been fully initialized.
- # Useful for per-environment configuration which depends on the framework being
- # fully initialized.
- def after_initialize(&after_initialize_block)
- after_initialize_blocks << after_initialize_block if after_initialize_block
- end
-
- # Returns the blocks added with Configuration#after_initialize
- def after_initialize_blocks
- @after_initialize_blocks ||= []
- end
-
- # Add a preparation callback that will run before every request in development
- # mode, or before the first request in production.
- #
- # See Dispatcher#to_prepare.
- def to_prepare(&callback)
- after_initialize do
- require 'dispatcher' unless defined?(::Dispatcher)
- Dispatcher.to_prepare(&callback)
- end
- end
-
- def middleware
- require 'action_controller'
- ActionController::Dispatcher.middleware
- end
-
- def builtin_directories
- # Include builtins only in the development environment.
- (environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
- end
-
- def framework_paths
- paths = %w(railties railties/lib activesupport/lib)
- paths << 'actionpack/lib' if frameworks.include?(:action_controller) || frameworks.include?(:action_view)
-
- [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
- paths << "#{framework.to_s.gsub('_', '')}/lib" if frameworks.include?(framework)
- end
-
- paths.map { |dir| "#{framework_root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
- end
-
- private
- def framework_root_path
- defined?(::RAILS_FRAMEWORK_ROOT) ? ::RAILS_FRAMEWORK_ROOT : "#{root_path}/vendor/rails"
- end
-
- def default_frameworks
- [ :active_record, :action_controller, :action_view, :action_mailer, :active_resource ]
- end
-
- def default_load_paths
- paths = []
-
- # Add the old mock paths only if the directories exists
- paths.concat(Dir["#{root_path}/test/mocks/#{environment}"]) if File.exists?("#{root_path}/test/mocks/#{environment}")
-
- # Add the app's controller directory
- paths.concat(Dir["#{root_path}/app/controllers/"])
-
- # Followed by the standard includes.
- paths.concat %w(
- app
- app/metal
- app/models
- app/controllers
- app/helpers
- app/services
- lib
- vendor
- ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
-
- paths.concat builtin_directories
- end
-
- # Doesn't matter since plugins aren't in load_paths yet.
- def default_load_once_paths
- []
- end
-
- def default_eager_load_paths
- %w(
- app/metal
- app/models
- app/controllers
- app/helpers
- ).map { |dir| "#{root_path}/#{dir}" }.select { |dir| File.directory?(dir) }
- end
-
- def default_log_path
- File.join(root_path, 'log', "#{environment}.log")
- end
-
- def default_log_level
- environment == 'production' ? :info : :debug
- end
-
- def default_database_configuration_file
- File.join(root_path, 'config', 'database.yml')
- end
-
- def default_routes_configuration_file
- File.join(root_path, 'config', 'routes.rb')
- end
-
- def default_view_path
- File.join(root_path, 'app', 'views')
- end
-
- def default_controller_paths
- paths = [File.join(root_path, 'app', 'controllers')]
- paths.concat builtin_directories
- paths
- end
-
- def default_dependency_loading
- true
- end
-
- def default_preload_frameworks
- false
- end
-
- def default_cache_classes
- true
- end
-
- def default_whiny_nils
- false
- end
-
- def default_plugins
- nil
- end
-
- def default_plugin_paths
- ["#{root_path}/vendor/plugins"]
- end
-
- def default_plugin_locators
- require 'rails/plugin/locator'
- locators = []
- locators << Plugin::GemLocator if defined? Gem
- locators << Plugin::FileSystemLocator
- end
-
- def default_plugin_loader
- require 'rails/plugin/loader'
- Plugin::Loader
- end
-
- def default_cache_store
- if File.exist?("#{root_path}/tmp/cache/")
- [ :file_store, "#{root_path}/tmp/cache/" ]
- else
- :memory_store
- end
- end
-
- def default_gems
- []
- end
-
- def default_i18n
- i18n = Rails::OrderedOptions.new
- i18n.load_path = []
-
- if File.exist?(File.join(RAILS_ROOT, 'config', 'locales'))
- i18n.load_path << Dir[File.join(RAILS_ROOT, 'config', 'locales', '*.{rb,yml}')]
- i18n.load_path.flatten!
- end
-
- i18n
- end
- end
-end
-
-# Needs to be duplicated from Active Support since its needed before Active
-# Support is available. Here both Options and Hash are namespaced to prevent
-# conflicts with other implementations AND with the classes residing in Active Support.
-class Rails::OrderedOptions < Array #:nodoc:
- def []=(key, value)
- key = key.to_sym
-
- if pair = find_pair(key)
- pair.pop
- pair << value
- else
- self << [key, value]
- end
- end
-
- def [](key)
- pair = find_pair(key.to_sym)
- pair ? pair.last : nil
- end
-
- def method_missing(name, *args)
- if name.to_s =~ /(.*)=$/
- self[$1.to_sym] = args.first
- else
- self[name]
- end
- end
-
- private
- def find_pair(key)
- self.each { |i| return i if i.first == key }
- return false
- end
-end
-
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 17e16f26fd..16dd0af44e 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -110,11 +110,6 @@ namespace :rails do
invoke_from_app_generator :create_prototype_files
end
- desc "Generate dispatcher files in RAILS_ROOT/public"
- task :generate_dispatchers do
- invoke_from_app_generator :create_dispatch_files
- end
-
desc "Add new scripts to the application script/ directory"
task :scripts do
invoke_from_app_generator :create_script_files
diff --git a/railties/rails.gemspec b/railties/rails.gemspec
index 659d6727ea..dc66e1efea 100644
--- a/railties/rails.gemspec
+++ b/railties/rails.gemspec
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
s.rdoc_options << '--exclude' << '.'
s.has_rdoc = false
- s.files = Dir['CHANGELOG', 'README', 'bin/**/*', 'builtin/**/*', 'guides/**/*', 'lib/**/*']
+ s.files = Dir['CHANGELOG', 'README', 'bin/**/*', 'builtin/**/*', 'guides/**/*', 'lib/**/{*,.[a-z]*}']
s.require_path = 'lib'
s.bindir = "bin"
s.executables = ["rails"]
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index 4510e6241c..6c6af0b2bf 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -25,11 +25,3 @@ if defined?(RAILS_ROOT)
else
RAILS_ROOT = File.dirname(__FILE__)
end
-
-def uses_gem(gem_name, test_name, version = '> 0')
- gem gem_name.to_s, version
- require gem_name.to_s
- yield
-rescue LoadError
- $stderr.puts "Skipping #{test_name} tests. `gem install #{gem_name}` and try again."
-end
diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb
new file mode 100644
index 0000000000..e8a4a4e158
--- /dev/null
+++ b/railties/test/application/console_test.rb
@@ -0,0 +1,52 @@
+require 'isolation/abstract_unit'
+
+class ConsoleTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+
+ # Load steps taken from rails/commands/console.rb
+ require "#{rails_root}/config/environment"
+ require 'rails/console_app'
+ require 'rails/console_with_helpers'
+ end
+
+ def test_app_method_should_return_integration_session
+ console_session = app
+ assert_not_nil console_session
+ assert_instance_of ActionController::Integration::Session, console_session
+ end
+
+ def test_new_session_should_return_integration_session
+ session = new_session
+ assert_not_nil session
+ assert_instance_of ActionController::Integration::Session, session
+ end
+
+ def test_reload_should_fire_preparation_callbacks
+ a = b = c = nil
+
+ # TODO: These should be defined on the initializer
+ ActionDispatch::Callbacks.to_prepare { a = b = c = 1 }
+ ActionDispatch::Callbacks.to_prepare { b = c = 2 }
+ ActionDispatch::Callbacks.to_prepare { c = 3 }
+
+ # Hide Reloading... output
+ silence_stream(STDOUT) do
+ reload!
+ end
+
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
+ def test_access_to_helpers
+ assert_not_nil helper
+ assert_instance_of ActionView::Base, helper
+ assert_equal 'Once upon a time in a world...',
+ helper.truncate('Once upon a time in a world far far away')
+ end
+end
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
new file mode 100644
index 0000000000..0d6eb4147a
--- /dev/null
+++ b/railties/test/application/generators_test.rb
@@ -0,0 +1,89 @@
+require "isolation/abstract_unit"
+
+module ApplicationTests
+ class GeneratorsTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ require "rails/generators"
+ build_app
+ boot_rails
+ end
+
+ test "generators default values" do
+ Rails::Initializer.run do |c|
+ assert_equal(true, c.generators.colorize_logging)
+ assert_equal({}, c.generators.aliases)
+ assert_equal({}, c.generators.options)
+ end
+ end
+
+ test "generators set rails options" do
+ Rails::Initializer.run do |c|
+ c.generators.orm = :datamapper
+ c.generators.test_framework = :rspec
+ expected = { :rails => { :orm => :datamapper, :test_framework => :rspec } }
+ assert_equal(expected, c.generators.options)
+ end
+ end
+
+ test "generators set rails aliases" do
+ Rails::Initializer.run do |c|
+ c.generators.aliases = { :rails => { :test_framework => "-w" } }
+ expected = { :rails => { :test_framework => "-w" } }
+ assert_equal expected, c.generators.aliases
+ end
+ end
+
+ test "generators aliases and options on initialization" do
+ Rails::Initializer.run do |c|
+ c.generators.rails :aliases => { :test_framework => "-w" }
+ c.generators.orm :datamapper
+ c.generators.test_framework :rspec
+ end
+
+ assert_equal :rspec, Rails::Generators.options[:rails][:test_framework]
+ assert_equal "-w", Rails::Generators.aliases[:rails][:test_framework]
+ end
+
+ test "generators no color on initialization" do
+ Rails::Initializer.run do |c|
+ c.generators.colorize_logging = false
+ end
+
+ assert_equal Thor::Base.shell, Thor::Shell::Basic
+ end
+
+ test "generators with hashes for options and aliases" do
+ Rails::Initializer.run do |c|
+ c.generators do |g|
+ g.orm :datamapper, :migration => false
+ g.plugin :aliases => { :generator => "-g" },
+ :generator => true
+ end
+
+ expected = {
+ :rails => { :orm => :datamapper },
+ :plugin => { :generator => true },
+ :datamapper => { :migration => false }
+ }
+
+ assert_equal expected, c.generators.options
+ assert_equal({ :plugin => { :generator => "-g" } }, c.generators.aliases)
+ end
+ end
+
+ test "generators with hashes are deep merged" do
+ Rails::Initializer.run do |c|
+ c.generators do |g|
+ g.orm :datamapper, :migration => false
+ g.plugin :aliases => { :generator => "-g" },
+ :generator => true
+ end
+ end
+
+ assert Rails::Generators.aliases.size >= 1
+ assert Rails::Generators.options.size >= 1
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/test/application/initializer_test.rb b/railties/test/application/initializer_test.rb
new file mode 100644
index 0000000000..f46bf2b656
--- /dev/null
+++ b/railties/test/application/initializer_test.rb
@@ -0,0 +1,194 @@
+require "isolation/abstract_unit"
+
+module ApplicationTests
+ class InitializerTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ test "initializing an application initializes rails" do
+ class MyApp < Rails::Application ; end
+
+ if RUBY_VERSION < '1.9'
+ $KCODE = ''
+ MyApp.new
+ assert_equal 'UTF8', $KCODE
+ else
+ Encoding.default_external = Encoding::US_ASCII
+ MyApp.new
+ assert_equal Encoding::UTF_8, Encoding.default_external
+ end
+ end
+
+ test "initializing an application adds the application paths to the load path" do
+ class MyApp < Rails::Application ; end
+
+ MyApp.new
+ assert $:.include?("#{app_path}/app/models")
+ end
+
+ test "adding an unknown framework raises an error" do
+ class MyApp < Rails::Application
+ config.frameworks << :action_foo
+ end
+
+ assert_raises RuntimeError do
+ MyApp.new
+ end
+ end
+
+ test "eager loading loads parent classes before children" do
+ app_file "lib/zoo.rb", <<-ZOO
+ class Zoo ; include ReptileHouse ; end
+ ZOO
+ app_file "lib/zoo/reptile_house.rb", <<-ZOO
+ module Zoo::ReptileHouse ; end
+ ZOO
+
+ Rails::Initializer.run do |config|
+ config.eager_load_paths = "#{app_path}/lib"
+ end
+
+ assert Zoo
+ end
+
+ test "load environment with global" do
+ app_file "config/environments/development.rb", "$initialize_test_set_from_env = 'success'"
+ assert_nil $initialize_test_set_from_env
+ Rails::Initializer.run { }
+ assert_equal "success", $initialize_test_set_from_env
+ end
+
+ test "action_controller load paths set only if action controller in use" do
+ assert_nothing_raised NameError do
+ Rails::Initializer.run do |config|
+ config.frameworks = []
+ end
+ end
+ end
+
+ test "action_pack is added to the load path if action_controller is required" do
+ Rails::Initializer.run do |config|
+ config.frameworks = [:action_controller]
+ end
+
+ assert $:.include?("#{framework_path}/actionpack/lib")
+ end
+
+ test "action_pack is added to the load path if action_view is required" do
+ Rails::Initializer.run do |config|
+ config.frameworks = [:action_view]
+ end
+
+ assert $:.include?("#{framework_path}/actionpack/lib")
+ end
+
+ test "after_initialize block works correctly" do
+ Rails::Initializer.run do |config|
+ config.after_initialize { $test_after_initialize_block1 = "success" }
+ config.after_initialize { $test_after_initialize_block2 = "congratulations" }
+ end
+
+ assert_equal "success", $test_after_initialize_block1
+ assert_equal "congratulations", $test_after_initialize_block2
+ end
+
+ test "after_initialize block works correctly when no block is passed" do
+ Rails::Initializer.run do |config|
+ config.after_initialize { $test_after_initialize_block1 = "success" }
+ config.after_initialize # don't pass a block, this is what we're testing!
+ config.after_initialize { $test_after_initialize_block2 = "congratulations" }
+ end
+
+ assert_equal "success", $test_after_initialize_block1
+ assert_equal "congratulations", $test_after_initialize_block2
+ end
+
+ # i18n
+ test "setting another default locale" do
+ Rails::Initializer.run do |config|
+ config.i18n.default_locale = :de
+ end
+ assert_equal :de, I18n.default_locale
+ end
+
+ test "no config locales dir present should return empty load path" do
+ FileUtils.rm_rf "#{app_path}/config/locales"
+ Rails::Initializer.run do |c|
+ assert_equal [], c.i18n.load_path
+ end
+ end
+
+ test "config locales dir present should be added to load path" do
+ Rails::Initializer.run do |c|
+ assert_equal ["#{app_path}/config/locales/en.yml"], c.i18n.load_path
+ end
+ end
+
+ test "config defaults should be added with config settings" do
+ Rails::Initializer.run do |c|
+ c.i18n.load_path << "my/other/locale.yml"
+ end
+
+ assert_equal [
+ "#{app_path}/config/locales/en.yml", "my/other/locale.yml"
+ ], Rails.application.config.i18n.load_path
+ end
+
+ # DB middleware
+ test "database middleware doesn't initialize when session store is not active_record" do
+ Rails::Initializer.run do |config|
+ config.action_controller.session_store = :cookie_store
+ end
+
+ assert !Rails.application.config.middleware.include?(ActiveRecord::SessionStore)
+ end
+
+ test "database middleware doesn't initialize when activerecord is not in frameworks" do
+ Rails::Initializer.run do |c|
+ c.frameworks = []
+ end
+ assert_equal [], Rails.application.config.middleware
+ end
+
+ test "database middleware initializes when session store is active record" do
+ Rails::Initializer.run do |c|
+ c.action_controller.session_store = :active_record_store
+ end
+
+ expects = [ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActiveRecord::SessionStore]
+ middleware = Rails.application.config.middleware.map { |m| m.klass }
+ assert_equal expects, middleware & expects
+ end
+
+ test "ensure database middleware doesn't use action_controller on initializing" do
+ Rails::Initializer.run do |c|
+ c.frameworks -= [:action_controller]
+ c.action_controller.session_store = :active_record_store
+ end
+
+ assert !Rails.application.config.middleware.include?(ActiveRecord::SessionStore)
+ end
+
+ # Pathview test
+ test "load view paths doesn't perform anything when action_view not in frameworks" do
+ Rails::Initializer.run do |c|
+ c.frameworks -= [:action_view]
+ end
+ assert_equal nil, ActionMailer::Base.template_root
+ assert_equal [], ActionController::Base.view_paths
+ end
+
+ # Rails root test
+ test "Rails.root == RAILS_ROOT" do
+ assert_equal RAILS_ROOT, Rails.root.to_s
+ end
+
+ test "Rails.root should be a Pathname" do
+ assert_instance_of Pathname, Rails.root
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/test/application/load_test.rb b/railties/test/application/load_test.rb
index 5158abdbb4..5c3d35fb16 100644
--- a/railties/test/application/load_test.rb
+++ b/railties/test/application/load_test.rb
@@ -40,7 +40,14 @@ module ApplicationTests
test "Rails.application is available after config.ru has been racked up" do
rackup
- assert Rails.application.new.is_a?(Rails::Application)
+ assert Rails.application.new < Rails::Application
+ end
+
+ # Passenger still uses AC::Dispatcher, so we need to
+ # keep it working for now
+ test "deprecated ActionController::Dispatcher still works" do
+ rackup
+ assert ActionController::Dispatcher.new < Rails::Application
end
test "the config object is available on the application object" do
diff --git a/railties/test/application/plugins_test.rb b/railties/test/application/plugins_test.rb
new file mode 100644
index 0000000000..81e7f4d88c
--- /dev/null
+++ b/railties/test/application/plugins_test.rb
@@ -0,0 +1,101 @@
+require "isolation/abstract_unit"
+
+module ApplicationTests
+ class PluginTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def assert_plugins(list_of_names, array_of_plugins, message=nil)
+ assert_equal list_of_names.map { |n| n.to_s }, array_of_plugins.map { |p| p.name }, message
+ end
+
+ def setup
+ build_app
+ boot_rails
+ @failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
+ # Tmp hax to get tests working
+ FileUtils.cp_r "#{File.dirname(__FILE__)}/../fixtures/plugins", "#{app_path}/vendor"
+ end
+
+ test "all plugins are loaded when registered plugin list is untouched" do
+ Rails::Initializer.run { }
+ assert_plugins [
+ :a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby
+ ], Rails.application.config.loaded_plugins, @failure_tip
+ end
+
+ test "no plugins are loaded if the configuration has an empty plugin list" do
+ Rails::Initializer.run { |c| c.plugins = [] }
+ assert_plugins [], Rails.application.config.loaded_plugins
+ end
+
+ test "only the specified plugins are located in the order listed" do
+ plugin_names = [:plugin_with_no_lib_dir, :acts_as_chunky_bacon]
+ Rails::Initializer.run { |c| c.plugins = plugin_names }
+ assert_plugins plugin_names, Rails.application.config.loaded_plugins
+ end
+
+ test "all plugins loaded after all" do
+ Rails::Initializer.run do |config|
+ config.plugins = [:stubby, :all, :acts_as_chunky_bacon]
+ end
+ assert_plugins [:stubby, :a, :engine, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], Rails.application.config.loaded_plugins, @failure_tip
+ end
+
+ test "plugin names may be strings" do
+ plugin_names = ['stubby', 'acts_as_chunky_bacon', :a, :plugin_with_no_lib_dir]
+ Rails::Initializer.run do |config|
+ config.plugins = ['stubby', 'acts_as_chunky_bacon', :a, :plugin_with_no_lib_dir]
+ end
+
+ assert_plugins plugin_names, Rails.application.config.loaded_plugins, @failure_tip
+ end
+
+ test "all plugins loaded when all is used" do
+ Rails::Initializer.run do |config|
+ config.plugins = [:stubby, :acts_as_chunky_bacon, :all]
+ end
+
+ assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :engine, :gemlike, :plugin_with_no_lib_dir], Rails.application.config.loaded_plugins, @failure_tip
+ end
+
+ test "all loaded plugins are added to the load paths" do
+ Rails::Initializer.run do |config|
+ config.plugins = [:stubby, :acts_as_chunky_bacon]
+ end
+
+ assert $LOAD_PATH.include?("#{app_path}/vendor/plugins/default/stubby/lib")
+ assert $LOAD_PATH.include?("#{app_path}/vendor/plugins/default/acts/acts_as_chunky_bacon/lib")
+ end
+
+ test "registering a plugin name that does not exist raises a load error" do
+ assert_raise(LoadError) do
+ Rails::Initializer.run do |config|
+ config.plugins = [:stubby, :acts_as_a_non_existant_plugin]
+ end
+ end
+ end
+
+ test "load error messages mention missing plugins and no others" do
+ valid_plugins = [:stubby, :acts_as_chunky_bacon]
+ invalid_plugins = [:non_existant_plugin1, :non_existant_plugin2]
+
+ begin
+ Rails::Initializer.run do |config|
+ config.plugins = [:stubby, :acts_as_chunky_bacon, :non_existant_plugin1, :non_existant_plugin2]
+ end
+ flunk "Expected a LoadError but did not get one"
+ rescue LoadError => e
+ assert_plugins valid_plugins, Rails.application.config.loaded_plugins, @failure_tip
+
+ invalid_plugins.each do |plugin|
+ assert_match(/#{plugin.to_s}/, e.message, "LoadError message should mention plugin '#{plugin}'")
+ end
+
+ valid_plugins.each do |plugin|
+ assert_no_match(/#{plugin.to_s}/, e.message, "LoadError message should not mention '#{plugin}'")
+ end
+ end
+ end
+
+ end
+end \ No newline at end of file
diff --git a/railties/test/console_app_test.rb b/railties/test/console_app_test.rb
deleted file mode 100644
index 1437e6d885..0000000000
--- a/railties/test/console_app_test.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require 'abstract_unit'
-
-require 'action_controller' # console_app uses 'action_controller/integration'
-
-require 'rails/dispatcher'
-require 'rails/console_app'
-
-module Rails
- def self.application
- ActionController::Routing::Routes
- end
-end
-
-# console_app sets Test::Unit.run to work around the at_exit hook in test/unit, which kills IRB
-if Test::Unit.respond_to?(:run=)
- Test::Unit.run = false
-
- class ConsoleAppTest < Test::Unit::TestCase
- def test_app_method_should_return_integration_session
- assert_nothing_thrown do
- console_session = app
- assert_not_nil console_session
- assert_instance_of ActionController::Integration::Session,
- console_session
- end
- end
-
- def test_reload_should_fire_preparation_callbacks
- a = b = c = nil
-
- ActionDispatch::Callbacks.to_prepare { a = b = c = 1 }
- ActionDispatch::Callbacks.to_prepare { b = c = 2 }
- ActionDispatch::Callbacks.to_prepare { c = 3 }
- ActionController::Routing::Routes.expects(:reload)
-
- reload!
-
- assert_equal 1, a
- assert_equal 2, b
- assert_equal 3, c
- end
- end
-end
diff --git a/railties/test/fcgi_dispatcher_test.rb b/railties/test/fcgi_dispatcher_test.rb
deleted file mode 100644
index 4d77a321a0..0000000000
--- a/railties/test/fcgi_dispatcher_test.rb
+++ /dev/null
@@ -1,268 +0,0 @@
-require 'abstract_unit'
-
-uses_gem "fcgi", "0.8.7" do
-
-require 'action_controller'
-require 'rails/fcgi_handler'
-
-module Rails
- def self.application
- ActionController::Routing::Routes
- end
-end
-
-class RailsFCGIHandlerTest < Test::Unit::TestCase
- def setup
- @log = StringIO.new
- @handler = RailsFCGIHandler.new(@log)
- end
-
- def test_process_restart
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @handler.expects(:process_request).once
- @handler.expects(:dispatcher_error).never
-
- @handler.expects(:when_ready).returns(:restart)
- @handler.expects(:close_connection).with(request)
- @handler.expects(:reload!).never
- @handler.expects(:restart!)
-
- @handler.process!
- end
-
- def test_process_exit
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @handler.expects(:process_request).once
- @handler.expects(:dispatcher_error).never
-
- @handler.expects(:when_ready).returns(:exit)
- @handler.expects(:close_connection).with(request)
- @handler.expects(:reload!).never
- @handler.expects(:restart!).never
-
- @handler.process!
- end
-
- def test_process_with_system_exit_exception
- request = mock
- FCGI.stubs(:each).yields(request)
-
- @handler.expects(:process_request).once.raises(SystemExit)
- @handler.stubs(:dispatcher_log)
- @handler.expects(:dispatcher_log).with(:info, regexp_matches(/^stopping/))
- @handler.expects(:dispatcher_error).never
-
- @handler.expects(:when_ready).never
- @handler.expects(:close_connection).never
- @handler.expects(:reload!).never
- @handler.expects(:restart!).never
-
- @handler.process!
- end
-
- def test_restart_handler_outside_request
- @handler.expects(:dispatcher_log).with(:info, "asked to restart ASAP")
- @handler.expects(:restart!).once
-
- @handler.send(:restart_handler, nil)
- assert_equal nil, @handler.when_ready
- end
-
- def test_install_signal_handler_should_log_on_bad_signal
- @handler.stubs(:trap).raises(ArgumentError)
-
- @handler.expects(:dispatcher_log).with(:warn, "Ignoring unsupported signal CHEESECAKE.")
- @handler.send(:install_signal_handler, "CHEESECAKE", nil)
- end
-
- def test_reload
- @handler.expects(:restore!)
- @handler.expects(:dispatcher_log).with(:info, "reloaded")
-
- @handler.send(:reload!)
- assert_nil @handler.when_ready
- end
-
-
- def test_reload_runs_gc_when_gc_request_period_set
- @handler.expects(:run_gc!)
- @handler.expects(:restore!)
- @handler.expects(:dispatcher_log).with(:info, "reloaded")
- @handler.gc_request_period = 10
- @handler.send(:reload!)
- end
-
- def test_reload_doesnt_run_gc_if_gc_request_period_isnt_set
- @handler.expects(:run_gc!).never
- @handler.expects(:restore!)
- @handler.expects(:dispatcher_log).with(:info, "reloaded")
- @handler.send(:reload!)
- end
-
- def test_restart!
- @handler.expects(:dispatcher_log).with(:info, "restarted")
- @handler.expects(:exec).returns('restarted')
- assert_equal 'restarted', @handler.send(:restart!)
- end
-
- def test_restore!
- $".expects(:replace)
- Dispatcher.expects(:reset_application!)
- ActionController::Routing::Routes.expects(:reload)
- @handler.send(:restore!)
- end
-
- def test_uninterrupted_processing
- request = mock
- FCGI.expects(:each).yields(request)
- @handler.expects(:process_request).with(request)
-
- @handler.process!
-
- assert_nil @handler.when_ready
- end
-end
-
-
-class RailsFCGIHandlerSignalsTest < Test::Unit::TestCase
- class ::RailsFCGIHandler
- attr_accessor :signal
- alias_method :old_gc_countdown, :gc_countdown
- def gc_countdown
- signal ? Process.kill(signal, $$) : old_gc_countdown
- end
- end
-
- def setup
- @log = StringIO.new
- @handler = RailsFCGIHandler.new(@log)
- @dispatcher = mock
- Dispatcher.stubs(:new).returns(@dispatcher)
- end
-
- def test_interrupted_via_HUP_when_not_in_request
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('HUP')
-
- @handler.expects(:reload!).once
- @handler.expects(:close_connection).never
- @handler.expects(:exit).never
-
- @handler.process!
- assert_equal :reload, @handler.when_ready
- end
-
- def test_interrupted_via_USR1_when_not_in_request
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('USR1')
- @handler.expects(:exit_handler).never
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).with(request).once
- @handler.expects(:exit).never
-
- @handler.process!
- assert_nil @handler.when_ready
- end
-
- def test_restart_via_USR2_when_in_request
- request = mock
- FCGI.expects(:each).once.yields(request)
- @handler.expects(:signal).times(2).returns('USR2')
- @handler.expects(:exit_handler).never
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).with(request).once
- @handler.expects(:exit).never
- @handler.expects(:restart!).once
-
- @handler.process!
- assert_equal :restart, @handler.when_ready
- end
-
- def test_interrupted_via_TERM
- request = mock
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.returns('TERM')
-
- @handler.expects(:reload!).never
- @handler.expects(:close_connection).never
-
- @handler.process!
- assert_nil @handler.when_ready
- end
-
- def test_runtime_exception_in_fcgi
- error = RuntimeError.new('foo')
- FCGI.expects(:each).times(2).raises(error)
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^retrying/))
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
- @handler.process!
- end
-
- def test_runtime_error_in_dispatcher
- request = mock
- error = RuntimeError.new('foo')
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.raises(error)
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^unhandled/))
- @handler.process!
- end
-
- def test_signal_exception_in_fcgi
- error = SignalException.new('USR2')
- FCGI.expects(:each).once.raises(error)
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
- @handler.process!
- end
-
- def test_signal_exception_in_dispatcher
- request = mock
- error = SignalException.new('USR2')
- FCGI.expects(:each).once.yields(request)
- ::Rack::Handler::FastCGI.expects(:serve).once.raises(error)
- @handler.expects(:dispatcher_error).with(error, regexp_matches(/^stopping/))
- @handler.process!
- end
-end
-
-
-class RailsFCGIHandlerPeriodicGCTest < Test::Unit::TestCase
- def setup
- @log = StringIO.new
- end
-
- def teardown
- GC.enable
- end
-
- def test_normal_gc
- @handler = RailsFCGIHandler.new(@log)
- assert_nil @handler.gc_request_period
-
- # When GC is enabled, GC.disable disables and returns false.
- assert_equal false, GC.disable
- end
-
- def test_periodic_gc
- @handler = RailsFCGIHandler.new(@log, 10)
- assert_equal 10, @handler.gc_request_period
-
- request = mock
- FCGI.expects(:each).times(10).yields(request)
-
- @handler.expects(:run_gc!).never
- 9.times { @handler.process! }
- @handler.expects(:run_gc!).once
- @handler.process!
-
- assert_nil @handler.when_ready
- end
-end
-end # uses_gem "fcgi"
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index afc0585fba..6e46c4ddc0 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -53,18 +53,6 @@ class AppGeneratorTest < GeneratorsTestCase
assert_match /Invalid value for \-\-database option/, content
end
- def test_dispatchers_are_not_added_by_default
- run_generator
- assert_no_file "public/dispatch.cgi"
- assert_no_file "public/dispatch.fcgi"
- end
-
- def test_dispatchers_are_added_if_required
- run_generator ["--with-dispatchers"]
- assert_file "public/dispatch.cgi"
- assert_file "public/dispatch.fcgi"
- end
-
def test_config_database_is_added_by_default
run_generator
assert_file "config/database.yml", /sqlite3/
diff --git a/railties/test/initializable_test.rb b/railties/test/initializable_test.rb
new file mode 100644
index 0000000000..7c8aed00c9
--- /dev/null
+++ b/railties/test/initializable_test.rb
@@ -0,0 +1,68 @@
+require 'abstract_unit'
+require 'rails/initializable'
+
+module InitializableTests
+
+ class Foo
+ extend Rails::Initializable
+
+ class << self
+ attr_accessor :foo, :bar
+ end
+
+ initializer :omg do
+ @foo ||= 0
+ @foo += 1
+ end
+ end
+
+ class Bar < Foo
+ initializer :bar do
+ @bar ||= 0
+ @bar += 1
+ end
+ end
+
+ module Word
+ extend Rails::Initializable
+
+ initializer :word do
+ $word = "bird"
+ end
+ end
+
+ class Basic < ActiveSupport::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ test "initializers run" do
+ Foo.initializers.run
+ assert_equal 1, Foo.foo
+ end
+
+ test "initializers are inherited" do
+ Bar.initializers.run
+ assert_equal [1, 1], [Bar.foo, Bar.bar]
+ end
+
+ test "initializers only get run once" do
+ Foo.initializers.run
+ Foo.initializers.run
+ assert_equal 1, Foo.foo
+ end
+
+ test "running initializers on children does not effect the parent" do
+ Bar.initializers.run
+ assert_nil Foo.foo
+ assert_nil Foo.bar
+ end
+
+ test "inherited initializers are the same objects" do
+ assert Foo.initializers[:foo].eql?(Bar.initializers[:foo])
+ end
+
+ test "initializing with modules" do
+ Word.initializers.run
+ assert_equal "bird", $word
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/test/initializer/initialize_i18n_test.rb b/railties/test/initializer/initialize_i18n_test.rb
new file mode 100644
index 0000000000..e909688817
--- /dev/null
+++ b/railties/test/initializer/initialize_i18n_test.rb
@@ -0,0 +1,51 @@
+require "isolation/abstract_unit"
+
+module InitializerTests
+ class InitializeI18nTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Isolation
+
+ def setup
+ build_app
+ boot_rails
+ end
+
+ # test_config_defaults_and_settings_should_be_added_to_i18n_defaults
+ test "i18n config defaults and settings should be added to i18n defaults" do
+ Rails::Initializer.run do |c|
+ c.i18n.load_path << "my/other/locale.yml"
+ end
+
+ #{RAILS_FRAMEWORK_ROOT}/railties/test/fixtures/plugins/engines/engine/config/locales/en.yml
+ assert_equal %W(
+ #{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/railties/tmp/app/config/locales/en.yml
+ my/other/locale.yml
+ ), I18n.load_path
+ end
+
+ test "i18n finds locale files in engines" do
+ app_file "vendor/plugins/engine/init.rb", ""
+ app_file "vendor/plugins/engine/app/models/hellos.rb", "class Hello ; end"
+ app_file "vendor/plugins/engine/lib/omg.rb", "puts 'omg'"
+ app_file "vendor/plugins/engine/config/locales/en.yml", "hello:"
+
+ Rails::Initializer.run do |c|
+ c.i18n.load_path << "my/other/locale.yml"
+ end
+
+ #{RAILS_FRAMEWORK_ROOT}/railties/test/fixtures/plugins/engines/engine/config/locales/en.yml
+ assert_equal %W(
+ #{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
+ #{RAILS_FRAMEWORK_ROOT}/actionpack/lib/action_view/locale/en.yml
+ #{app_path}/config/locales/en.yml
+ my/other/locale.yml
+ #{app_path}/vendor/plugins/engine/config/locales/en.yml
+ ), I18n.load_path
+ end
+ end
+end \ No newline at end of file
diff --git a/railties/test/initializer/path_test.rb b/railties/test/initializer/path_test.rb
index a4264bc31c..72ff8d88e0 100644
--- a/railties/test/initializer/path_test.rb
+++ b/railties/test/initializer/path_test.rb
@@ -12,7 +12,7 @@ class PathsTest < Test::Unit::TestCase
ActionController::Base.session_store = nil
end
end
- @paths = Rails::Initializer.default.config.paths
+ @paths = Rails.application.config.paths
end
def root(*path)
diff --git a/railties/test/initializer_test.rb b/railties/test/initializer_test.rb
index b67db9c835..80e774b7b7 100644
--- a/railties/test/initializer_test.rb
+++ b/railties/test/initializer_test.rb
@@ -6,490 +6,8 @@ require 'action_view'
require 'action_mailer'
require 'active_record'
-# Mocks out the configuration
-module Rails
- def self.configuration
- Rails::Configuration.new
- end
-
- module Generators
- def self.clear_aliases!
- @aliases = nil
- end
-
- def self.clear_options!
- @@options = nil
- end
- end
-end
-
-
-class ConfigurationMock < Rails::Configuration
- attr_reader :environment_path
-
- def initialize(envpath)
- super()
- @environment_path = envpath
- end
-end
-
-class Initializer_load_environment_Test < Test::Unit::TestCase
- def test_load_environment_with_constant
- config = ConfigurationMock.new("#{File.dirname(__FILE__)}/fixtures/environment_with_constant.rb")
- assert_nil $initialize_test_set_from_env
- Rails::Initializer.run(:load_environment, config)
- assert_equal "success", $initialize_test_set_from_env
- ensure
- $initialize_test_set_from_env = nil
- end
-end
-
-class Initializer_eager_loading_Test < Test::Unit::TestCase
- def setup
- @config = ConfigurationMock.new("")
- @config.cache_classes = true
- @config.load_paths = [File.expand_path(File.dirname(__FILE__) + "/fixtures/eager")]
- @config.eager_load_paths = [File.expand_path(File.dirname(__FILE__) + "/fixtures/eager")]
- @initializer = Rails::Initializer.default
- @initializer.config = @config
- @initializer.run(:set_load_path)
- @initializer.run(:set_autoload_paths)
- end
-
- def test_eager_loading_loads_parent_classes_before_children
- assert_nothing_raised do
- @initializer.run(:load_application_classes)
- end
- end
-end
-
-class Initializer_after_initialize_with_blocks_environment_Test < Test::Unit::TestCase
- def setup
- config = ConfigurationMock.new("")
- config.after_initialize do
- $test_after_initialize_block1 = "success"
- end
- config.after_initialize do
- $test_after_initialize_block2 = "congratulations"
- end
- assert_nil $test_after_initialize_block1
- assert_nil $test_after_initialize_block2
-
- config.expects(:gems_dependencies_loaded).returns(true)
- Rails::Initializer.run(:after_initialize, config)
- end
-
- def teardown
- $test_after_initialize_block1 = nil
- $test_after_initialize_block2 = nil
- end
-
- def test_should_have_called_the_first_after_initialize_block
- assert_equal "success", $test_after_initialize_block1
- end
-
- def test_should_have_called_the_second_after_initialize_block
- assert_equal "congratulations", $test_after_initialize_block2
- end
-end
-
-class Initializer_after_initialize_with_no_block_environment_Test < Test::Unit::TestCase
- def setup
- config = ConfigurationMock.new("")
- config.after_initialize do
- $test_after_initialize_block1 = "success"
- end
- config.after_initialize # don't pass a block, this is what we're testing!
- config.after_initialize do
- $test_after_initialize_block2 = "congratulations"
- end
- assert_nil $test_after_initialize_block1
-
- config.expects(:gems_dependencies_loaded).returns(true)
- Rails::Initializer.run(:after_initialize, config)
- end
-
- def teardown
- $test_after_initialize_block1 = nil
- $test_after_initialize_block2 = nil
- end
-
- def test_should_have_called_the_first_after_initialize_block
- assert_equal "success", $test_after_initialize_block1, "should still get set"
- end
-
- def test_should_have_called_the_second_after_initialize_block
- assert_equal "congratulations", $test_after_initialize_block2
- end
-end
-
-class ConfigurationFrameworkPathsTests < Test::Unit::TestCase
- def setup
- @config = Rails::Configuration.new
- @config.frameworks.clear
- @initializer = Rails::Initializer.default
- @initializer.config = @config
-
- File.stubs(:directory?).returns(true)
- Rails::Initializer.run(:set_root_path, @config)
- end
-
- def test_minimal
- expected = %w(railties railties/lib activesupport/lib)
- assert_equal expected.map {|e| "#{@config.framework_root_path}/#{e}"}, @config.framework_paths
- end
-
- def test_actioncontroller_or_actionview_add_actionpack
- @config.frameworks << :action_controller
- assert_framework_path "actionpack/lib"
-
- @config.frameworks = [:action_view]
- assert_framework_path 'actionpack/lib'
- end
-
- def test_paths_for_ar_ares_and_mailer
- [:active_record, :action_mailer, :active_resource, :action_web_service].each do |framework|
- @config.frameworks = [framework]
- assert_framework_path "#{framework.to_s.gsub('_', '')}/lib"
- end
- end
-
- def test_unknown_framework_raises_error
- @config.frameworks << :action_foo
-
- Class.any_instance.expects(:require).raises(LoadError)
-
- assert_raise RuntimeError do
- @initializer.run(:require_frameworks)
- end
- end
-
- def test_action_mailer_load_paths_set_only_if_action_mailer_in_use
- @config.frameworks = [:action_controller]
- @initializer.config = @config
- @initializer.run :require_frameworks
-
- assert_nothing_raised NameError do
- @initializer.run :load_view_paths
- end
- end
-
- def test_action_controller_load_paths_set_only_if_action_controller_in_use
- @config.frameworks = []
- @initializer.run :require_frameworks
-
- assert_nothing_raised NameError do
- @initializer.run :load_view_paths
- end
- end
-
- protected
- def assert_framework_path(path)
- assert @config.framework_paths.include?("#{@config.framework_root_path}/#{path}"),
- "<#{path.inspect}> not found among <#{@config.framework_paths.inspect}>"
- end
-end
-
require 'plugin_test_helper'
-class InitializerPluginLoadingTests < Test::Unit::TestCase
- def setup
- @configuration = Rails::Configuration.new
- @configuration.frameworks -= [:action_mailer]
- @configuration.plugin_paths << plugin_fixture_root_path
- @initializer = Rails::Initializer.default
- @initializer.config = @configuration
- @valid_plugin_path = plugin_fixture_path('default/stubby')
- @empty_plugin_path = plugin_fixture_path('default/empty')
- end
-
- def test_no_plugins_are_loaded_if_the_configuration_has_an_empty_plugin_list
- only_load_the_following_plugins! []
- @initializer.run :load_plugins
- assert_equal [], @configuration.loaded_plugins
- end
-
- def test_only_the_specified_plugins_are_located_in_the_order_listed
- plugin_names = [:plugin_with_no_lib_dir, :acts_as_chunky_bacon]
- only_load_the_following_plugins! plugin_names
- load_plugins!
- assert_plugins plugin_names, @configuration.loaded_plugins
- end
-
- def test_all_plugins_are_loaded_when_registered_plugin_list_is_untouched
- failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
- load_plugins!
- assert_plugins [:a, :acts_as_chunky_bacon, :engine, :gemlike, :plugin_with_no_lib_dir, :stubby], @configuration.loaded_plugins, failure_tip
- end
-
- def test_all_plugins_loaded_when_all_is_used
- plugin_names = [:stubby, :acts_as_chunky_bacon, :all]
- only_load_the_following_plugins! plugin_names
- load_plugins!
- failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
- assert_plugins [:stubby, :acts_as_chunky_bacon, :a, :engine, :gemlike, :plugin_with_no_lib_dir], @configuration.loaded_plugins, failure_tip
- end
-
- def test_all_plugins_loaded_after_all
- plugin_names = [:stubby, :all, :acts_as_chunky_bacon]
- only_load_the_following_plugins! plugin_names
- load_plugins!
- failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
- assert_plugins [:stubby, :a, :engine, :gemlike, :plugin_with_no_lib_dir, :acts_as_chunky_bacon], @configuration.loaded_plugins, failure_tip
- end
-
- def test_plugin_names_may_be_strings
- plugin_names = ['stubby', 'acts_as_chunky_bacon', :a, :plugin_with_no_lib_dir]
- only_load_the_following_plugins! plugin_names
- load_plugins!
- failure_tip = "It's likely someone has added a new plugin fixture without updating this list"
- assert_plugins plugin_names, @configuration.loaded_plugins, failure_tip
- end
-
- def test_registering_a_plugin_name_that_does_not_exist_raises_a_load_error
- only_load_the_following_plugins! [:stubby, :acts_as_a_non_existant_plugin]
- assert_raise(LoadError) do
- load_plugins!
- end
- end
-
- def test_load_error_messages_mention_missing_plugins_and_no_others
- valid_plugin_names = [:stubby, :acts_as_chunky_bacon]
- invalid_plugin_names = [:non_existant_plugin1, :non_existant_plugin2]
- only_load_the_following_plugins!( valid_plugin_names + invalid_plugin_names )
- begin
- load_plugins!
- flunk "Expected a LoadError but did not get one"
- rescue LoadError => e
- failure_tip = "It's likely someone renamed or deleted plugin fixtures without updating this test"
- assert_plugins valid_plugin_names, @configuration.loaded_plugins, failure_tip
- invalid_plugin_names.each do |plugin|
- assert_match(/#{plugin.to_s}/, e.message, "LoadError message should mention plugin '#{plugin}'")
- end
- valid_plugin_names.each do |plugin|
- assert_no_match(/#{plugin.to_s}/, e.message, "LoadError message should not mention '#{plugin}'")
- end
-
- end
- end
-
- def test_should_ensure_all_loaded_plugins_load_paths_are_added_to_the_load_path
- only_load_the_following_plugins! [:stubby, :acts_as_chunky_bacon]
-
- @initializer.run(:add_plugin_load_paths)
-
- assert $LOAD_PATH.include?(File.join(plugin_fixture_path('default/stubby'), 'lib'))
- assert $LOAD_PATH.include?(File.join(plugin_fixture_path('default/acts/acts_as_chunky_bacon'), 'lib'))
- end
-
- private
-
- def load_plugins!
- @initializer.run(:add_plugin_load_paths)
- @initializer.run(:load_plugins)
- end
-end
-
-class InitializerGeneratorsTests < Test::Unit::TestCase
-
- def setup
- @configuration = Rails::Configuration.new
- @initializer = Rails::Initializer.default
- @initializer.config = @configuration
- end
-
- def test_generators_default_values
- assert_equal(true, @configuration.generators.colorize_logging)
- assert_equal({}, @configuration.generators.aliases)
- assert_equal({}, @configuration.generators.options)
- end
-
- def test_generators_set_rails_options
- @configuration.generators.orm = :datamapper
- @configuration.generators.test_framework = :rspec
- expected = { :rails => { :orm => :datamapper, :test_framework => :rspec } }
- assert_equal expected, @configuration.generators.options
- end
-
- def test_generators_set_rails_aliases
- @configuration.generators.aliases = { :rails => { :test_framework => "-w" } }
- expected = { :rails => { :test_framework => "-w" } }
- assert_equal expected, @configuration.generators.aliases
- end
-
- def test_generators_aliases_and_options_on_initialization
- @configuration.generators.rails :aliases => { :test_framework => "-w" }
- @configuration.generators.orm :datamapper
- @configuration.generators.test_framework :rspec
-
- @initializer.run(:initialize_generators)
-
- assert_equal :rspec, Rails::Generators.options[:rails][:test_framework]
- assert_equal "-w", Rails::Generators.aliases[:rails][:test_framework]
- end
-
- def test_generators_no_color_on_initialization
- @configuration.generators.colorize_logging = false
- @initializer.run(:initialize_generators)
- assert_equal Thor::Base.shell, Thor::Shell::Basic
- end
-
- def test_generators_with_hashes_for_options_and_aliases
- @configuration.generators do |g|
- g.orm :datamapper, :migration => false
- g.plugin :aliases => { :generator => "-g" },
- :generator => true
- end
-
- expected = {
- :rails => { :orm => :datamapper },
- :plugin => { :generator => true },
- :datamapper => { :migration => false }
- }
-
- assert_equal expected, @configuration.generators.options
- assert_equal({ :plugin => { :generator => "-g" } }, @configuration.generators.aliases)
- end
-
- def test_generators_with_hashes_are_deep_merged
- @configuration.generators do |g|
- g.orm :datamapper, :migration => false
- g.plugin :aliases => { :generator => "-g" },
- :generator => true
- end
- @initializer.run(:initialize_generators)
-
- assert Rails::Generators.aliases.size >= 1
- assert Rails::Generators.options.size >= 1
- end
-
- protected
-
- def teardown
- Rails::Generators.clear_aliases!
- Rails::Generators.clear_options!
- end
-end
-
-class InitializerSetupI18nTests < Test::Unit::TestCase
- def test_no_config_locales_dir_present_should_return_empty_load_path
- File.stubs(:exist?).returns(false)
- assert_equal [], Rails::Configuration.new.i18n.load_path
- end
-
- def test_config_locales_dir_present_should_be_added_to_load_path
- File.stubs(:exist?).returns(true)
- Dir.stubs(:[]).returns([ "my/test/locale.yml" ])
- assert_equal [ "my/test/locale.yml" ], Rails::Configuration.new.i18n.load_path
- end
-
- def test_config_defaults_should_be_added_with_config_settings
- File.stubs(:exist?).returns(true)
- Dir.stubs(:[]).returns([ "my/test/locale.yml" ])
-
- config = Rails::Configuration.new
- config.i18n.load_path << "my/other/locale.yml"
-
- assert_equal [ "my/test/locale.yml", "my/other/locale.yml" ], config.i18n.load_path
- end
-
- def test_config_defaults_and_settings_should_be_added_to_i18n_defaults
- File.stubs(:exist?).returns(true)
- Dir.stubs(:[]).returns([ "my/test/locale.yml" ])
-
- config = Rails::Configuration.new
- config.i18n.load_path << "my/other/locale.yml"
-
- Rails::Initializer.run(:initialize_i18n, config)
- assert_equal [
- File.expand_path(File.dirname(__FILE__) + "/../../activesupport/lib/active_support/locale/en.yml"),
- File.expand_path(File.dirname(__FILE__) + "/../../actionpack/lib/action_view/locale/en.yml"),
- File.expand_path(File.dirname(__FILE__) + "/../../activemodel/lib/active_model/locale/en.yml"),
- File.expand_path(File.dirname(__FILE__) + "/../../activerecord/lib/active_record/locale/en.yml"),
- File.expand_path(File.dirname(__FILE__) + "/../../railties/test/fixtures/plugins/engines/engine/config/locales/en.yml"),
- "my/test/locale.yml",
- "my/other/locale.yml" ], I18n.load_path.collect { |path| path =~ /\.\./ ? File.expand_path(path) : path }
- end
-
- def test_setting_another_default_locale
- config = Rails::Configuration.new
- config.i18n.default_locale = :de
- Rails::Initializer.run(:initialize_i18n, config)
- assert_equal :de, I18n.default_locale
- end
-end
-
-class InitializerDatabaseMiddlewareTest < Test::Unit::TestCase
- def setup
- @config = Rails::Configuration.new
- @config.frameworks = [:active_record, :action_controller, :action_view]
- end
-
- def test_initialize_database_middleware_doesnt_perform_anything_when_active_record_not_in_frameworks
- @config.frameworks.clear
- @config.expects(:middleware).never
- Rails::Initializer.run(:initialize_database_middleware, @config)
- end
-
- def test_database_middleware_initializes_when_session_store_is_active_record
- store = ActionController::Base.session_store
- ActionController::Base.session_store = ActiveRecord::SessionStore
-
- @config.middleware.expects(:insert_before).with(:"ActiveRecord::SessionStore", ActiveRecord::ConnectionAdapters::ConnectionManagement)
- @config.middleware.expects(:insert_before).with(:"ActiveRecord::SessionStore", ActiveRecord::QueryCache)
-
- Rails::Initializer.run(:initialize_database_middleware, @config)
- ensure
- ActionController::Base.session_store = store
- end
-
- def test_database_middleware_doesnt_initialize_when_session_store_is_not_active_record
- store = ActionController::Base.session_store
- ActionController::Base.session_store = ActionDispatch::Session::CookieStore
-
- # Define the class, so we don't have to actually make it load
- eval("class ActiveRecord::ConnectionAdapters::ConnectionManagement; end")
-
- @config.middleware.expects(:use).with(ActiveRecord::ConnectionAdapters::ConnectionManagement)
- @config.middleware.expects(:use).with(ActiveRecord::QueryCache)
-
- Rails::Initializer.run(:initialize_database_middleware, @config)
- ensure
- ActionController::Base.session_store = store
- end
-
- def test_ensure_database_middleware_doesnt_use_action_controller_on_initializing
- @config.frameworks -= [:action_controller]
- store = ActionController::Base.session_store
- ActionController::Base.session_store = ActiveRecord::SessionStore
-
- @config.middleware.expects(:use).with(ActiveRecord::ConnectionAdapters::ConnectionManagement)
- @config.middleware.expects(:use).with(ActiveRecord::QueryCache)
-
- Rails::Initializer.run(:initialize_database_middleware, @config)
- ensure
- ActionController::Base.session_store = store
- @config.frameworks += [:action_controller]
- end
-end
-
-class InitializerViewPathsTest < Test::Unit::TestCase
- def setup
- @config = Rails::Configuration.new
- @config.frameworks = [:action_view, :action_controller, :action_mailer]
-
- ActionController::Base.stubs(:view_paths).returns(stub)
- ActionMailer::Base.stubs(:view_paths).returns(stub)
- end
-
- def test_load_view_paths_doesnt_perform_anything_when_action_view_not_in_frameworks
- @config.frameworks -= [:action_view]
- ActionController::Base.view_paths.expects(:load!).never
- ActionMailer::Base.view_paths.expects(:load!).never
- Rails::Initializer.run(:load_view_paths, @config)
- end
-end
-
class RailsRootTest < Test::Unit::TestCase
def test_rails_dot_root_equals_rails_root
assert_equal RAILS_ROOT, Rails.root.to_s
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 869e8429cf..f83e0151a4 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -7,6 +7,8 @@
# It is also good to know what is the bare minimum to get
# Rails booted up.
+require 'fileutils'
+
# TODO: Remove rubygems when possible
require 'rubygems'
require 'test/unit'
@@ -30,6 +32,14 @@ module TestHelpers
def app_path(*args)
tmp_path(*%w[app] + args)
end
+
+ def framework_path
+ RAILS_FRAMEWORK_ROOT
+ end
+
+ def rails_root
+ app_path
+ end
end
module Rack
@@ -87,7 +97,8 @@ module TestHelpers
end
def app_file(path, contents)
- File.open(app_path(path), 'w') do |f|
+ FileUtils.mkdir_p File.dirname("#{app_path}/#{path}")
+ File.open("#{app_path}/#{path}", 'w') do |f|
f.puts contents
end
end
diff --git a/railties/test/new_initializer_test.rb b/railties/test/new_initializer_test.rb
deleted file mode 100644
index 67b66fb088..0000000000
--- a/railties/test/new_initializer_test.rb
+++ /dev/null
@@ -1,165 +0,0 @@
-require 'abstract_unit'
-require 'active_support/ruby/shim'
-require 'rails/initializer'
-
-class InitializerRunnerTest < ActiveSupport::TestCase
-
- def setup
- @runner = Rails::Initializer::Runner.new
- end
-
- test "A new runner can be created" do
- assert @runner
- end
-
- test "The initializers actually get run when the runner is run" do
- state = nil
-
- @runner.add :foo do
- run { state = true }
- end
-
- @runner.run
- assert state
- end
-
- test "By default, initializers get run in the order that they are added" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- @runner.run
- assert_equal [:first, :second], state
- end
-
- test "Raises an exception if :before or :after are specified, but don't exist" do
- assert_raise(Rails::Initializer::Error) do
- @runner.add(:fail, :before => :whale) { 1 }
- end
-
- assert_raise(Rails::Initializer::Error) do
- @runner.add(:fail, :after => :whale) { 1 }
- end
- end
-
- test "When adding an initializer, specifying :after allows you to move an initializer after another" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- @runner.add :third, :after => :first do
- run { state << :third }
- end
-
- @runner.run
- assert_equal [:first, :third, :second], state
- end
-
- test "An initializer can be deleted" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- @runner.delete(:second)
-
- @runner.run
- assert_equal [:first], state
- end
-
- test "A runner can be initialized with an existing runner, which it copies" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- Rails::Initializer::Runner.new(@runner).run
- assert_equal [:first, :second], state
- end
-
- test "A child runner can be still be modified without modifying the parent" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- new_runner = Rails::Initializer::Runner.new(@runner)
- new_runner.add :trois do
- run { state << :trois }
- end
- new_runner.delete(:second)
-
- new_runner.run
- assert_equal [:first, :trois], state
- state.clear
- @runner.run
- assert_equal [:first, :second], state
- end
-
- test "A child runner that is modified does not modify any other children of the same parent" do
- state = []
-
- @runner.add :first do
- run { state << :first }
- end
-
- @runner.add :second do
- run { state << :second }
- end
-
- child_one = Rails::Initializer::Runner.new(@runner)
- child_two = Rails::Initializer::Runner.new(@runner)
-
- child_one.delete(:second)
- child_two.run
-
- assert_equal [:first, :second], state
- end
-
- test "It does not run the initializer block immediately" do
- state = []
- @runner.add :first do
- state << :first
- end
-
- assert_equal [], state
- end
-
- test "It runs the block when the runner is run" do
- state = []
- @runner.add :first do
- state << :first
- end
-
- @runner.run
- assert_equal [:first], state
- end
-
-end \ No newline at end of file
diff --git a/railties/test/plugin_loader_test.rb b/railties/test/plugin_loader_test.rb
index 99301347b6..0b43c49bb2 100644
--- a/railties/test/plugin_loader_test.rb
+++ b/railties/test/plugin_loader_test.rb
@@ -5,10 +5,13 @@ $:.unshift File.dirname(__FILE__) + "/../../actionmailer/lib"
require 'action_controller'
require 'action_mailer'
-# Mocks out the configuration
-module Rails
- def self.configuration
- Rails::Configuration.new
+# TODO: Rewrite all these tests
+class FakeInitializerSlashApplication
+ attr_reader :config
+ alias configuration config
+
+ def initialize
+ @config = Rails::Configuration.new
end
end
@@ -18,10 +21,10 @@ class TestPluginLoader < Test::Unit::TestCase
def setup
reset_load_path!
- @configuration = Rails::Configuration.new
+ @initializer = FakeInitializerSlashApplication.new
+ @configuration = @initializer.config
+ Rails.application = @initializer
@configuration.plugin_paths << plugin_fixture_root_path
- @initializer = Rails::Initializer.default
- @initializer.config = @configuration
@valid_plugin_path = plugin_fixture_path('default/stubby')
@empty_plugin_path = plugin_fixture_path('default/empty')
diff --git a/railties/test/plugin_locator_test.rb b/railties/test/plugin_locator_test.rb
index da1548dee1..ef57e7ed4c 100644
--- a/railties/test/plugin_locator_test.rb
+++ b/railties/test/plugin_locator_test.rb
@@ -1,5 +1,15 @@
require 'plugin_test_helper'
+# TODO: Rewrite all these tests
+class FakeInitializerSlashApplication
+ attr_reader :config
+ alias configuration config
+
+ def initialize
+ @config = Rails::Configuration.new
+ end
+end
+
class PluginLocatorTest < Test::Unit::TestCase
def test_should_require_subclasses_to_implement_the_plugins_method
assert_raise(RuntimeError) do
@@ -23,12 +33,12 @@ end
class PluginFileSystemLocatorTest < Test::Unit::TestCase
def setup
- @configuration = Rails::Configuration.new
+ @initializer = FakeInitializerSlashApplication.new
+ @configuration = @initializer.config
+ Rails.application = @initializer
# We need to add our testing plugin directory to the plugin paths so
# the locator knows where to look for our plugins
@configuration.plugin_paths << plugin_fixture_root_path
- @initializer = Rails::Initializer.default
- @initializer.config = @configuration
@locator = Rails::Plugin::FileSystemLocator.new(@initializer)
@valid_plugin_path = plugin_fixture_path('default/stubby')
@empty_plugin_path = plugin_fixture_path('default/empty')
diff --git a/railties/test/plugin_test.rb b/railties/test/plugin_test.rb
index ae03ea4662..199adcfe39 100644
--- a/railties/test/plugin_test.rb
+++ b/railties/test/plugin_test.rb
@@ -1,9 +1,20 @@
require 'plugin_test_helper'
+# TODO: Rewrite all these tests
+class FakeInitializerSlashApplication
+ attr_reader :config
+ alias configuration config
+
+ def initialize
+ @config = Rails::Configuration.new
+ end
+end
+
class PluginTest < Test::Unit::TestCase
def setup
- @initializer = Rails::Initializer.default
- @initializer.config = Rails::Configuration.new
+ @initializer = FakeInitializerSlashApplication.new
+ @configuration = @initializer.config
+ Rails.application = @initializer
@valid_plugin_path = plugin_fixture_path('default/stubby')
@empty_plugin_path = plugin_fixture_path('default/empty')
@gemlike_plugin_path = plugin_fixture_path('default/gemlike')