aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Rakefile8
-rw-r--r--actionmailer/Rakefile6
-rw-r--r--actionmailer/lib/action_mailer/vendor/tmail.rb1
-rw-r--r--actionpack/CHANGELOG2
-rw-r--r--actionpack/Rakefile8
-rw-r--r--actionpack/examples/minimal.rb34
-rw-r--r--actionpack/lib/action_controller.rb13
-rw-r--r--actionpack/lib/action_controller/abstract.rb3
-rw-r--r--actionpack/lib/action_controller/abstract/base.rb52
-rw-r--r--actionpack/lib/action_controller/abstract/callbacks.rb6
-rw-r--r--actionpack/lib/action_controller/abstract/layouts.rb2
-rw-r--r--actionpack/lib/action_controller/abstract/logger.rb37
-rw-r--r--actionpack/lib/action_controller/abstract/renderer.rb29
-rw-r--r--actionpack/lib/action_controller/base/base.rb7
-rw-r--r--actionpack/lib/action_controller/base/chained/benchmarking.rb2
-rw-r--r--actionpack/lib/action_controller/base/chained/filters.rb9
-rw-r--r--actionpack/lib/action_controller/base/http_authentication.rb6
-rw-r--r--actionpack/lib/action_controller/base/layout.rb4
-rw-r--r--actionpack/lib/action_controller/base/redirect.rb4
-rw-r--r--actionpack/lib/action_controller/dispatch/dispatcher.rb100
-rw-r--r--actionpack/lib/action_controller/dispatch/middlewares.rb3
-rw-r--r--actionpack/lib/action_controller/new_base.rb2
-rw-r--r--actionpack/lib/action_controller/new_base/base.rb121
-rw-r--r--actionpack/lib/action_controller/new_base/compatibility.rb66
-rw-r--r--actionpack/lib/action_controller/new_base/hide_actions.rb4
-rw-r--r--actionpack/lib/action_controller/new_base/http.rb20
-rw-r--r--actionpack/lib/action_controller/new_base/layouts.rb2
-rw-r--r--actionpack/lib/action_controller/new_base/redirector.rb19
-rw-r--r--actionpack/lib/action_controller/new_base/renderer.rb27
-rw-r--r--actionpack/lib/action_controller/new_base/rescuable.rb53
-rw-r--r--actionpack/lib/action_controller/new_base/testing.rb2
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb2
-rw-r--r--actionpack/lib/action_controller/routing.rb4
-rw-r--r--actionpack/lib/action_controller/routing/builder.rb2
-rw-r--r--actionpack/lib/action_controller/routing/route.rb8
-rw-r--r--actionpack/lib/action_controller/testing/process.rb14
-rw-r--r--actionpack/lib/action_controller/testing/process2.rb1
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb2
-rw-r--r--actionpack/lib/action_dispatch.rb15
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb1
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb1
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb7
-rw-r--r--actionpack/lib/action_dispatch/http/status_codes.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb40
-rw-r--r--actionpack/lib/action_dispatch/middleware/failsafe.rb52
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb10
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb87
-rw-r--r--actionpack/lib/action_view.rb14
-rw-r--r--actionpack/lib/action_view/base.rb3
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb9
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb13
-rw-r--r--actionpack/lib/action_view/render/partials.rb32
-rw-r--r--actionpack/lib/action_view/render/rendering.rb5
-rw-r--r--actionpack/lib/action_view/template/handlers.rb2
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb1
-rw-r--r--actionpack/test/abstract_controller/abstract_controller_test.rb7
-rw-r--r--actionpack/test/abstract_controller/callbacks_test.rb19
-rw-r--r--actionpack/test/abstract_controller/test_helper.rb4
-rw-r--r--actionpack/test/abstract_unit.rb6
-rw-r--r--actionpack/test/abstract_unit2.rb84
-rw-r--r--actionpack/test/activerecord/active_record_store_test.rb6
-rw-r--r--actionpack/test/activerecord/polymorphic_routes_test.rb1
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb23
-rw-r--r--actionpack/test/controller/addresses_render_test.rb1
-rw-r--r--actionpack/test/controller/base_test.rb3
-rw-r--r--actionpack/test/controller/capture_test.rb1
-rw-r--r--actionpack/test/controller/dispatcher_test.rb34
-rw-r--r--actionpack/test/controller/filters_test.rb1
-rw-r--r--actionpack/test/controller/helper_test.rb4
-rw-r--r--actionpack/test/controller/render_js_test.rb37
-rw-r--r--actionpack/test/controller/render_json_test.rb80
-rw-r--r--actionpack/test/controller/render_other_test.rb222
-rw-r--r--actionpack/test/controller/render_test.rb343
-rw-r--r--actionpack/test/controller/render_xml_test.rb81
-rw-r--r--actionpack/test/controller/rescue_test.rb14
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb5
-rw-r--r--actionpack/test/new_base/redirect_test.rb1
-rw-r--r--actionpack/test/new_base/render_action_test.rb23
-rw-r--r--actionpack/test/new_base/render_file_test.rb110
-rw-r--r--actionpack/test/new_base/render_layout_test.rb16
-rw-r--r--actionpack/test/new_base/render_partial_test.rb27
-rw-r--r--actionpack/test/new_base/render_template_test.rb76
-rw-r--r--actionpack/test/new_base/render_test.rb6
-rw-r--r--actionpack/test/new_base/render_xml_test.rb11
-rw-r--r--actionpack/test/new_base/test_helper.rb26
-rw-r--r--actionpack/test/template/form_options_helper_test.rb22
-rw-r--r--actionpack/test/template/number_helper_test.rb4
-rw-r--r--actionpack/test/template/text_helper_test.rb7
-rwxr-xr-xactivemodel/Rakefile6
-rw-r--r--activemodel/test/state_machine/event_test.rb1
-rw-r--r--activemodel/test/state_machine/state_transition_test.rb1
-rw-r--r--activerecord/CHANGELOG2
-rw-r--r--activerecord/Rakefile23
-rw-r--r--activerecord/examples/simple.rb14
-rw-r--r--activerecord/lib/active_record.rb5
-rwxr-xr-xactiverecord/lib/active_record/associations.rb4
-rw-r--r--activerecord/lib/active_record/associations/association_collection.rb9
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb16
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb8
-rwxr-xr-xactiverecord/lib/active_record/base.rb29
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/quoting.rb2
-rwxr-xr-xactiverecord/lib/active_record/connection_adapters/abstract_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql_adapter.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb1
-rw-r--r--activerecord/lib/active_record/dirty.rb4
-rw-r--r--activerecord/lib/active_record/fixtures.rb1
-rw-r--r--activerecord/lib/active_record/i18n_interpolation_deprecation.rb26
-rw-r--r--activerecord/lib/active_record/migration.rb10
-rw-r--r--activerecord/lib/active_record/named_scope.rb14
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb3
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb4
-rw-r--r--activerecord/lib/active_record/serialization.rb17
-rw-r--r--activerecord/lib/active_record/serializers/xml_serializer.rb5
-rw-r--r--activerecord/lib/active_record/session_store.rb10
-rw-r--r--activerecord/lib/active_record/validations.rb5
-rw-r--r--activerecord/test/cases/aaa_create_tables_test.rb24
-rw-r--r--activerecord/test/cases/aggregations_test.rb1
-rw-r--r--activerecord/test/cases/associations/eager_load_nested_include_test.rb1
-rw-r--r--activerecord/test/cases/associations/eager_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb1
-rw-r--r--activerecord/test/cases/associations/has_many_associations_test.rb39
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb9
-rwxr-xr-xactiverecord/test/cases/base_test.rb1
-rw-r--r--activerecord/test/cases/finder_test.rb11
-rw-r--r--activerecord/test/cases/helper.rb19
-rw-r--r--activerecord/test/cases/named_scope_test.rb37
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb1
-rw-r--r--activerecord/test/cases/validations_i18n_test.rb34
-rw-r--r--activerecord/test/fixtures/people.yml5
-rw-r--r--activerecord/test/models/company_in_module.rb2
-rw-r--r--activerecord/test/models/person.rb1
-rw-r--r--activerecord/test/schema/schema.rb6
-rw-r--r--activerecord/test/schema/schema2.rb6
-rw-r--r--activeresource/Rakefile7
-rw-r--r--activeresource/examples/simple.rb16
-rw-r--r--activeresource/lib/active_resource/base.rb4
-rw-r--r--activeresource/test/base/custom_methods_test.rb1
-rw-r--r--activeresource/test/base/load_test.rb1
-rw-r--r--activeresource/test/base_test.rb1
-rw-r--r--activesupport/Rakefile2
-rw-r--r--activesupport/lib/active_support/core_ext/object/conversions.rb3
-rw-r--r--activesupport/lib/active_support/json.rb11
-rw-r--r--activesupport/lib/active_support/json/backends/jsongem.rb9
-rw-r--r--activesupport/lib/active_support/json/backends/yaml.rb9
-rw-r--r--activesupport/lib/active_support/memoizable.rb1
-rw-r--r--activesupport/lib/active_support/xml_mini/jdom.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/libxml.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/nokogiri.rb16
-rw-r--r--activesupport/lib/active_support/xml_mini/rexml.rb14
-rw-r--r--activesupport/test/json/decoding_test.rb3
-rw-r--r--activesupport/test/xml_mini/nokogiri_engine_test.rb13
-rw-r--r--activesupport/test/xml_mini/rexml_engine_test.rb14
-rw-r--r--railties/Rakefile12
-rw-r--r--railties/builtin/rails_info/rails/info.rb10
-rw-r--r--railties/configs/routes.rb2
-rw-r--r--railties/lib/commands/performance/profiler.rb2
-rw-r--r--railties/lib/console_app.rb5
-rw-r--r--railties/lib/initializer.rb7
-rw-r--r--railties/lib/rails/plugin.rb2
-rw-r--r--railties/lib/rails/plugin/loader.rb12
-rw-r--r--railties/lib/rails/plugin/locator.rb2
-rw-r--r--railties/lib/rails_generator/generators/applications/app/template_runner.rb2
-rw-r--r--railties/lib/rails_generator/generators/components/model/templates/model.rb2
-rw-r--r--railties/lib/rails_generator/scripts.rb2
-rw-r--r--railties/lib/tasks/gems.rake8
-rw-r--r--railties/test/abstract_unit.rb1
-rw-r--r--railties/test/plugin_test_helper.rb1
-rw-r--r--railties/test/rails_info_test.rb2
-rwxr-xr-x[-rw-r--r--]tools/profile_requires (renamed from tools/profile_requires.rb)14
175 files changed, 1996 insertions, 979 deletions
diff --git a/Rakefile b/Rakefile
index 8f4c891074..fbb7f2213c 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,6 +1,5 @@
require 'rake'
require 'rake/rdoctask'
-require 'rake/contrib/sshpublisher'
env = %(PKG_BUILD="#{ENV['PKG_BUILD']}") if ENV['PKG_BUILD']
@@ -13,12 +12,14 @@ end
desc 'Run all tests by default'
task :default => :test
-%w(test rdoc pgem package release).each do |task_name|
+%w(test isolated_test rdoc pgem package release).each do |task_name|
desc "Run #{task_name} task for all projects"
task task_name do
+ errors = []
PROJECTS.each do |project|
- system %(cd #{project} && #{env} #{$0} #{task_name})
+ system(%(cd #{project} && #{env} #{$0} #{task_name})) || errors << project
end
+ fail("Errors in #{errors.join(', ')}") unless errors.empty?
end
end
@@ -74,6 +75,7 @@ end
desc "Publish API docs for Rails as a whole and for each component"
task :pdoc => :rdoc do
+ require 'rake/contrib/sshpublisher'
Rake::SshDirPublisher.new("wrath.rubyonrails.org", "public_html/api", "doc/rdoc").upload
PROJECTS.each do |project|
system %(cd #{project} && #{env} #{$0} pdoc)
diff --git a/actionmailer/Rakefile b/actionmailer/Rakefile
index f06f18ff76..24c25abc8b 100644
--- a/actionmailer/Rakefile
+++ b/actionmailer/Rakefile
@@ -28,6 +28,12 @@ Rake::TestTask.new { |t|
t.warning = false
}
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir.glob("test/*_test.rb").all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
# Generate the RDoc documentation
Rake::RDocTask.new { |rdoc|
diff --git a/actionmailer/lib/action_mailer/vendor/tmail.rb b/actionmailer/lib/action_mailer/vendor/tmail.rb
index 51d36cdd0d..60555605f6 100644
--- a/actionmailer/lib/action_mailer/vendor/tmail.rb
+++ b/actionmailer/lib/action_mailer/vendor/tmail.rb
@@ -12,6 +12,7 @@ end
require 'tmail'
+require 'active_support/core_ext/kernel/reporting'
silence_warnings do
TMail::Encoder.const_set("MAX_LINE_LEN", 200)
end
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 204f5ae272..c1dc6f2ab4 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*
+* Instead of checking Rails.env.test? in Failsafe middleware, check env["rails.raise_exceptions"] [Bryan Helmkamp]
+
* Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes]
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index ef76eedfd7..41b190130e 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -22,7 +22,7 @@ task :default => [ :test ]
# Run the unit tests
desc "Run all unit tests"
-task :test => [:test_action_pack, :test_active_record_integration, :test_new_base]
+task :test => [:test_action_pack, :test_active_record_integration]
Rake::TestTask.new(:test_action_pack) do |t|
t.libs << "test"
@@ -34,6 +34,12 @@ Rake::TestTask.new(:test_action_pack) do |t|
t.verbose = true
#t.warning = true
end
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir.glob("test/{controller,dispatch,template}/**/*_test.rb").all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
diff --git a/actionpack/examples/minimal.rb b/actionpack/examples/minimal.rb
new file mode 100644
index 0000000000..84a8499daf
--- /dev/null
+++ b/actionpack/examples/minimal.rb
@@ -0,0 +1,34 @@
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
+require 'action_controller'
+require 'action_controller/new_base' if ENV['NEW']
+require 'benchmark'
+
+class BaseController < ActionController::Base
+ def index
+ render :text => ''
+ end
+end
+
+n = (ENV['N'] || 10000).to_i
+input = StringIO.new('')
+
+def call_index(controller, input, n)
+ n.times do
+ controller.action(:index).call({ 'rack.input' => input })
+ end
+
+ puts controller.name
+ status, headers, body = controller.action(:index).call({ 'rack.input' => input })
+
+ puts status
+ puts headers.to_yaml
+ puts '---'
+ body.each do |part|
+ puts part
+ end
+ puts '---'
+end
+
+elapsed = Benchmark.realtime { call_index BaseController, input, n }
+
+puts "%dms elapsed, %d requests/sec" % [1000 * elapsed, n / elapsed]
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index ab78bc9222..39083a84e9 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -21,16 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-begin
- require 'active_support'
-rescue LoadError
- activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
- if File.directory?(activesupport_path)
- $:.unshift activesupport_path
- require 'active_support'
- end
-end
-require 'active_support/core/all'
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift activesupport_path if File.directory?(activesupport_path)
+require 'active_support'
require File.join(File.dirname(__FILE__), "action_pack")
diff --git a/actionpack/lib/action_controller/abstract.rb b/actionpack/lib/action_controller/abstract.rb
index 3f5c4a185f..48e33282ec 100644
--- a/actionpack/lib/action_controller/abstract.rb
+++ b/actionpack/lib/action_controller/abstract.rb
@@ -1,3 +1,6 @@
+require "active_support/core_ext/module/attr_internal"
+require "active_support/core_ext/module/delegation"
+
module AbstractController
autoload :Base, "action_controller/abstract/base"
autoload :Callbacks, "action_controller/abstract/callbacks"
diff --git a/actionpack/lib/action_controller/abstract/base.rb b/actionpack/lib/action_controller/abstract/base.rb
index ab9aed0b26..1f2f096dae 100644
--- a/actionpack/lib/action_controller/abstract/base.rb
+++ b/actionpack/lib/action_controller/abstract/base.rb
@@ -1,4 +1,16 @@
+require 'active_support/core_ext/module/attr_internal'
+
module AbstractController
+ class Error < StandardError; end
+
+ class DoubleRenderError < Error
+ DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
+
+ def initialize(message = nil)
+ super(message || DEFAULT_MESSAGE)
+ end
+ end
+
class Base
attr_internal :response_body
@@ -13,6 +25,15 @@ module AbstractController
end
alias_method :abstract?, :abstract
+
+ def inherited(klass)
+ ::AbstractController::Base.subclasses << klass.to_s
+ super
+ end
+
+ def subclasses
+ @subclasses ||= []
+ end
def internal_methods
controller = self
@@ -48,12 +69,13 @@ module AbstractController
end
def process(action_name)
- unless respond_to_action?(action_name)
+ @_action_name = action_name = action_name.to_s
+
+ unless action_name = method_for_action(action_name)
raise ActionNotFound, "The action '#{action_name}' could not be found"
end
-
- @_action_name = action_name
- process_action
+
+ process_action(action_name)
self
end
@@ -63,23 +85,31 @@ module AbstractController
self.class.action_methods
end
+ def action_method?(action)
+ action_methods.include?(action)
+ end
+
# It is possible for respond_to?(action_name) to be false and
# respond_to?(:action_missing) to be false if respond_to_action?
# is overridden in a subclass. For instance, ActionController::Base
# overrides it to include the case where a template matching the
# action_name is found.
- def process_action
- if respond_to?(action_name) then send(action_name)
- elsif respond_to?(:action_missing, true) then action_missing(action_name)
- end
+ def process_action(method_name)
+ send(method_name)
end
-
+
+ def _handle_action_missing
+ action_missing(@_action_name)
+ end
+
# Override this to change the conditions that will raise an
# ActionNotFound error. If you accept a difference case,
# you must handle it by also overriding process_action and
# handling the case.
- def respond_to_action?(action_name)
- action_methods.include?(action_name) || respond_to?(:action_missing, true)
+ def method_for_action(action_name)
+ if action_method?(action_name) then action_name
+ elsif respond_to?(:action_missing, true) then "_handle_action_missing"
+ end
end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/abstract/callbacks.rb b/actionpack/lib/action_controller/abstract/callbacks.rb
index 6e15b3e81b..51b968c694 100644
--- a/actionpack/lib/action_controller/abstract/callbacks.rb
+++ b/actionpack/lib/action_controller/abstract/callbacks.rb
@@ -5,11 +5,11 @@ module AbstractController
depends_on ActiveSupport::NewCallbacks
included do
- define_callbacks :process_action
+ define_callbacks :process_action, "response_body"
end
- def process_action
- _run_process_action_callbacks(action_name) do
+ def process_action(method_name)
+ _run_process_action_callbacks(method_name) do
super
end
end
diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb
index e48b8b2b4b..35d5e85ed9 100644
--- a/actionpack/lib/action_controller/abstract/layouts.rb
+++ b/actionpack/lib/action_controller/abstract/layouts.rb
@@ -51,7 +51,7 @@ module AbstractController
end
def _render_template(template, options)
- _action_view._render_template_with_layout(template, options[:_layout], options)
+ _action_view._render_template_from_controller(template, options[:_layout], options, options[:_partial])
end
private
diff --git a/actionpack/lib/action_controller/abstract/logger.rb b/actionpack/lib/action_controller/abstract/logger.rb
index 5fb78f1755..750a5c9fb6 100644
--- a/actionpack/lib/action_controller/abstract/logger.rb
+++ b/actionpack/lib/action_controller/abstract/logger.rb
@@ -1,9 +1,44 @@
+require 'active_support/core_ext/class/attribute_accessors'
+
module AbstractController
module Logger
extend ActiveSupport::DependencyModule
+ class DelayedLog
+ def initialize(&blk)
+ @blk = blk
+ end
+
+ def to_s
+ @blk.call
+ end
+ alias to_str to_s
+ end
+
included do
cattr_accessor :logger
end
+
+ def process(action)
+ ret = super
+
+ if logger
+ log = DelayedLog.new do
+ "\n\nProcessing #{self.class.name}\##{action_name} " \
+ "to #{request.formats} " \
+ "(for #{request_origin}) [#{request.method.to_s.upcase}]"
+ end
+
+ logger.info(log)
+ end
+
+ ret
+ end
+
+ def request_origin
+ # this *needs* to be cached!
+ # otherwise you'd get different results if calling it more than once
+ @request_origin ||= "#{request.remote_ip} at #{Time.now.to_s(:db)}"
+ end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb
index b58688c9da..f2044a35ec 100644
--- a/actionpack/lib/action_controller/abstract/renderer.rb
+++ b/actionpack/lib/action_controller/abstract/renderer.rb
@@ -1,15 +1,6 @@
require "action_controller/abstract/logger"
module AbstractController
- class AbstractControllerError < StandardError; end
- class DoubleRenderError < AbstractControllerError
- DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"."
-
- def initialize(message = nil)
- super(message || DEFAULT_MESSAGE)
- end
- end
-
module Renderer
extend ActiveSupport::DependencyModule
@@ -27,12 +18,12 @@ module AbstractController
@_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self)
end
- def render(options = {})
+ def render(*args)
if response_body
raise AbstractController::DoubleRenderError, "OMG"
end
- self.response_body = render_to_body(options)
+ self.response_body = render_to_body(*args)
end
# Raw rendering of a template to a Rack-compatible body.
@@ -43,10 +34,16 @@ module AbstractController
# :api: plugin
def render_to_body(options = {})
name = options[:_template_name] || action_name
-
- options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix])
-
- _render_template(options[:_template], options)
+
+ # TODO: Refactor so we can just use the normal template logic for this
+ if options[:_partial_object]
+ _action_view._render_partial_from_controller(options)
+ else
+ options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats},
+ options[:_prefix], options[:_partial])
+
+ _render_template(options[:_template], options)
+ end
end
# Raw rendering of a template to a string.
@@ -60,7 +57,7 @@ module AbstractController
end
def _render_template(template, options)
- _action_view._render_template_with_layout(template)
+ _action_view._render_template_from_controller(template, nil, options, options[:_partial])
end
def view_paths() _view_paths end
diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb
index d25801b17b..c59068c628 100644
--- a/actionpack/lib/action_controller/base/base.rb
+++ b/actionpack/lib/action_controller/base/base.rb
@@ -1,5 +1,7 @@
require 'action_controller/deprecated'
require 'set'
+require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/module/attr_internal'
module ActionController #:nodoc:
class ActionControllerError < StandardError #:nodoc:
@@ -366,9 +368,8 @@ module ActionController #:nodoc:
attr_reader :template
def action(name, env)
- # HACK: For global rescue to have access to the original request and response
- request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
- response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
+ request = ActionDispatch::Request.new(env)
+ response = ActionDispatch::Response.new
self.action_name = name && name.to_s
process(request, response).to_a
end
diff --git a/actionpack/lib/action_controller/base/chained/benchmarking.rb b/actionpack/lib/action_controller/base/chained/benchmarking.rb
index 066150f58a..66e9e9c31d 100644
--- a/actionpack/lib/action_controller/base/chained/benchmarking.rb
+++ b/actionpack/lib/action_controller/base/chained/benchmarking.rb
@@ -1,4 +1,4 @@
-require 'benchmark'
+require 'active_support/core_ext/benchmark'
module ActionController #:nodoc:
# The benchmarking module times the performance of actions and reports to the logger. If the Active Record
diff --git a/actionpack/lib/action_controller/base/chained/filters.rb b/actionpack/lib/action_controller/base/chained/filters.rb
index 9022b8b279..e121c0129d 100644
--- a/actionpack/lib/action_controller/base/chained/filters.rb
+++ b/actionpack/lib/action_controller/base/chained/filters.rb
@@ -160,7 +160,7 @@ module ActionController #:nodoc:
def convert_only_and_except_options_to_sets_of_strings(opts)
[:only, :except].each do |key|
if values = opts[key]
- opts[key] = Array(values).map(&:to_s).to_set
+ opts[key] = Array(values).map {|val| val.to_s }.to_set
end
end
end
@@ -571,12 +571,7 @@ module ActionController #:nodoc:
# Returns an array of Filter objects for this controller.
def filter_chain
- if chain = read_inheritable_attribute('filter_chain')
- return chain
- else
- write_inheritable_attribute('filter_chain', FilterChain.new)
- return filter_chain
- end
+ read_inheritable_attribute('filter_chain') || write_inheritable_attribute('filter_chain', FilterChain.new)
end
# Returns all the before filters for this class and all its ancestors.
diff --git a/actionpack/lib/action_controller/base/http_authentication.rb b/actionpack/lib/action_controller/base/http_authentication.rb
index b6b5267c66..fa8ecea408 100644
--- a/actionpack/lib/action_controller/base/http_authentication.rb
+++ b/actionpack/lib/action_controller/base/http_authentication.rb
@@ -1,3 +1,5 @@
+require 'active_support/base64'
+
module ActionController
module HttpAuthentication
# Makes it dead easy to do HTTP Basic authentication.
@@ -276,7 +278,7 @@ module ActionController
t = time.to_i
hashed = [t, secret_key]
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
- Base64.encode64("#{t}:#{digest}").gsub("\n", '')
+ ActiveSupport::Base64.encode64("#{t}:#{digest}").gsub("\n", '')
end
# Might want a shorter timeout depending on whether the request
@@ -285,7 +287,7 @@ module ActionController
# allow a user to use new nonce without prompting user again for their
# username and password.
def validate_nonce(request, value, seconds_to_timeout=5*60)
- t = Base64.decode64(value).split(":").first.to_i
+ t = ActiveSupport::Base64.decode64(value).split(":").first.to_i
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
end
diff --git a/actionpack/lib/action_controller/base/layout.rb b/actionpack/lib/action_controller/base/layout.rb
index 1ad5191c73..cf5f46a32b 100644
--- a/actionpack/lib/action_controller/base/layout.rb
+++ b/actionpack/lib/action_controller/base/layout.rb
@@ -1,3 +1,7 @@
+require 'active_support/core_ext/enumerable'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/class/inheritable_attributes'
+
module ActionController #:nodoc:
module Layout #:nodoc:
def self.included(base)
diff --git a/actionpack/lib/action_controller/base/redirect.rb b/actionpack/lib/action_controller/base/redirect.rb
index 4849caac0a..7e10f614e2 100644
--- a/actionpack/lib/action_controller/base/redirect.rb
+++ b/actionpack/lib/action_controller/base/redirect.rb
@@ -70,7 +70,9 @@ module ActionController
def redirect_to_full_url(url, status)
raise DoubleRenderError if performed?
logger.info("Redirected to #{url}") if logger && logger.info?
- response.redirect(url, interpret_status(status))
+ response.status = interpret_status(status)
+ response.location = url.gsub(/[\r\n]/, '')
+ response.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
@performed_redirect = true
end
diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb
index 63866caed9..9ad1cadfd3 100644
--- a/actionpack/lib/action_controller/dispatch/dispatcher.rb
+++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb
@@ -1,87 +1,65 @@
+require 'active_support/core_ext/module/delegation'
+
module ActionController
# Dispatches requests to the appropriate controller and takes care of
# reloading the app after each request when Dependencies.load? is true.
class Dispatcher
+ cattr_accessor :prepare_each_request
+ self.prepare_each_request = false
+
+ cattr_accessor :router
+ self.router = Routing::Routes
+
+ cattr_accessor :middleware
+ self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
+ middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
+ middleware.instance_eval(File.read(middlewares), middlewares, 1)
+ end
+
class << self
def define_dispatcher_callbacks(cache_classes)
unless cache_classes
+ # Run prepare callbacks before every request in development mode
+ self.prepare_each_request = true
+
# Development mode callbacks
- before_dispatch :reload_application
- after_dispatch :cleanup_application
+ ActionDispatch::Callbacks.before_dispatch do |app|
+ ActionController::Dispatcher.router.reload
+ end
+
+ ActionDispatch::Callbacks.after_dispatch do
+ # Cleanup the application before processing the current request.
+ ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
+ ActiveSupport::Dependencies.clear
+ ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
+ end
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
end
if defined?(ActiveRecord)
- to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
+ to_prepare(:activerecord_instantiate_observers) do
+ ActiveRecord::Base.instantiate_observers
+ end
end
- after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
+ if Base.logger && Base.logger.respond_to?(:flush)
+ after_dispatch do
+ Base.logger.flush
+ end
+ end
to_prepare do
I18n.reload!
end
end
- # Add a preparation callback. Preparation callbacks are run before every
- # request in development mode, and before the first request in production
- # mode.
- #
- # An optional identifier may be supplied for the callback. If provided,
- # to_prepare may be called again with the same identifier to replace the
- # existing callback. Passing an identifier is a suggested practice if the
- # code adding a preparation block may be reloaded.
- def to_prepare(identifier = nil, &block)
- @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
- callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
- @prepare_dispatch_callbacks.replace_or_append!(callback)
- end
+ delegate :to_prepare, :prepare_dispatch, :before_dispatch, :after_dispatch,
+ :to => ActionDispatch::Callbacks
- def run_prepare_callbacks
- new.send :run_callbacks, :prepare_dispatch
+ def new
+ @@middleware.build(@@router)
end
end
-
- cattr_accessor :router
- self.router = Routing::Routes
-
- cattr_accessor :middleware
- self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
- middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
- middleware.instance_eval(File.read(middlewares), middlewares, 1)
- end
-
- include ActiveSupport::Callbacks
- define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
-
- def initialize
- @app = @@middleware.build(@@router)
- freeze
- end
-
- def call(env)
- run_callbacks :before_dispatch
- @app.call(env)
- ensure
- run_callbacks :after_dispatch, :enumerator => :reverse_each
- end
-
- def reload_application
- # Run prepare callbacks before every request in development mode
- run_callbacks :prepare_dispatch
-
- @@router.reload
- end
-
- def cleanup_application
- # Cleanup the application before processing the current request.
- ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
- ActiveSupport::Dependencies.clear
- ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
- end
-
- def flush_logger
- Base.logger.flush
- end
end
end
diff --git a/actionpack/lib/action_controller/dispatch/middlewares.rb b/actionpack/lib/action_controller/dispatch/middlewares.rb
index f99637b109..b25ed3fd3f 100644
--- a/actionpack/lib/action_controller/dispatch/middlewares.rb
+++ b/actionpack/lib/action_controller/dispatch/middlewares.rb
@@ -2,10 +2,11 @@ use "Rack::Lock", :if => lambda {
!ActionController::Base.allow_concurrency
}
-use "ActionDispatch::Failsafe"
use "ActionDispatch::ShowExceptions", lambda { ActionController::Base.consider_all_requests_local }
+use "ActionDispatch::Callbacks", lambda { ActionController::Dispatcher.prepare_each_request }
use "ActionDispatch::Rescue", lambda {
controller = (::ApplicationController rescue ActionController::Base)
+ # TODO: Replace with controller.action(:_rescue_action)
controller.method(:rescue_action)
}
diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb
index 8a7de1476c..bc47713529 100644
--- a/actionpack/lib/action_controller/new_base.rb
+++ b/actionpack/lib/action_controller/new_base.rb
@@ -5,7 +5,9 @@ module ActionController
autoload :Http, "action_controller/new_base/http"
autoload :Layouts, "action_controller/new_base/layouts"
autoload :Rails2Compatibility, "action_controller/new_base/compatibility"
+ autoload :Redirector, "action_controller/new_base/redirector"
autoload :Renderer, "action_controller/new_base/renderer"
+ autoload :Rescue, "action_controller/new_base/rescuable"
autoload :Testing, "action_controller/new_base/testing"
autoload :UrlFor, "action_controller/new_base/url_for"
diff --git a/actionpack/lib/action_controller/new_base/base.rb b/actionpack/lib/action_controller/new_base/base.rb
index 4892886341..c25ffd5c84 100644
--- a/actionpack/lib/action_controller/new_base/base.rb
+++ b/actionpack/lib/action_controller/new_base/base.rb
@@ -8,17 +8,44 @@ module ActionController
include ActionController::HideActions
include ActionController::UrlFor
+ include ActionController::Redirector
include ActionController::Renderer
include ActionController::Layouts
include ActionController::ConditionalGet
-
+
# Legacy modules
include SessionManagement
include ActionDispatch::StatusCodes
-
+
# Rails 2.x compatibility
include ActionController::Rails2Compatibility
-
+
+ # TODO: Extract into its own module
+ # This should be moved together with other normalizing behavior
+ module ImplicitRender
+ def process_action(method_name)
+ ret = super
+ render if response_body.nil?
+ ret
+ end
+
+ def _implicit_render
+ render
+ end
+
+ def method_for_action(action_name)
+ super || begin
+ if view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path)
+ "_implicit_render"
+ end
+ end
+ end
+ end
+
+ include ImplicitRender
+
+ include ActionController::Rescue
+
def self.inherited(klass)
::ActionController::Base.subclasses << klass.to_s
super
@@ -34,29 +61,83 @@ module ActionController
end
end
- def render(action = action_name, options = {})
+ def render_to_body(action = nil, options = {})
if action.is_a?(Hash)
options, action = action, nil
- else
- options.merge! :action => action
+ elsif action.is_a?(String) || action.is_a?(Symbol)
+ key = case action = action.to_s
+ when %r{^/} then :file
+ when %r{/} then :template
+ else :action
+ end
+ options.merge! key => action
+ elsif action
+ options.merge! :partial => action
end
- super(options)
- end
-
- def render_to_body(options = {})
- options = {:template => options} if options.is_a?(String)
- super
- end
-
- def process_action
- ret = super
- render if response_body.nil?
- ret
+ if options.key?(:action) && options[:action].to_s.index("/")
+ options[:template] = options.delete(:action)
+ end
+
+ # options = {:template => options.to_s} if options.is_a?(String) || options.is_a?(Symbol)
+ super(options) || " "
end
- def respond_to_action?(action_name)
- super || view_paths.find_by_parts?(action_name.to_s, {:formats => formats, :locales => [I18n.locale]}, controller_path)
+ # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
+ #
+ # * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
+ # * <tt>Record</tt> - The URL will be generated by calling url_for with the +options+, which will reference a named URL for that record.
+ # * <tt>String</tt> starting with <tt>protocol://</tt> (like <tt>http://</tt>) - Is passed straight through as the target for redirection.
+ # * <tt>String</tt> not containing a protocol - The current protocol and host is prepended to the string.
+ # * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
+ # Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
+ #
+ # Examples:
+ # redirect_to :action => "show", :id => 5
+ # redirect_to post
+ # redirect_to "http://www.rubyonrails.org"
+ # redirect_to "/images/screenshot.jpg"
+ # redirect_to articles_url
+ # redirect_to :back
+ #
+ # The redirection happens as a "302 Moved" header unless otherwise specified.
+ #
+ # Examples:
+ # redirect_to post_url(@post), :status=>:found
+ # redirect_to :action=>'atom', :status=>:moved_permanently
+ # redirect_to post_url(@post), :status=>301
+ # redirect_to :action=>'atom', :status=>302
+ #
+ # When using <tt>redirect_to :back</tt>, if there is no referrer,
+ # RedirectBackError will be raised. You may specify some fallback
+ # behavior for this case by rescuing RedirectBackError.
+ def redirect_to(options = {}, response_status = {}) #:doc:
+ raise ActionControllerError.new("Cannot redirect to nil!") if options.nil?
+
+ status = if options.is_a?(Hash) && options.key?(:status)
+ interpret_status(options.delete(:status))
+ elsif response_status.key?(:status)
+ interpret_status(response_status[:status])
+ else
+ 302
+ end
+
+ url = case options
+ # The scheme name consist of a letter followed by any combination of
+ # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
+ # characters; and is terminated by a colon (":").
+ when %r{^\w[\w\d+.-]*:.*}
+ options
+ when String
+ request.protocol + request.host_with_port + options
+ when :back
+ raise RedirectBackError unless refer = request.headers["Referer"]
+ refer
+ else
+ url_for(options)
+ end
+
+ super(url, status)
end
end
end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/new_base/compatibility.rb b/actionpack/lib/action_controller/new_base/compatibility.rb
index 4655a94923..0a283887b6 100644
--- a/actionpack/lib/action_controller/new_base/compatibility.rb
+++ b/actionpack/lib/action_controller/new_base/compatibility.rb
@@ -8,27 +8,51 @@ module ActionController
::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
cattr_accessor :session_options
- self.send(:class_variable_set, "@@session_options", {})
+ self.session_options = {}
cattr_accessor :allow_concurrency
- self.send(:class_variable_set, "@@allow_concurrency", false)
+ self.allow_concurrency = false
cattr_accessor :param_parsers
- self.send(:class_variable_set, "@@param_parsers", { Mime::MULTIPART_FORM => :multipart_form,
- Mime::URL_ENCODED_FORM => :url_encoded_form,
- Mime::XML => :xml_simple,
- Mime::JSON => :json })
+ self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form,
+ Mime::URL_ENCODED_FORM => :url_encoded_form,
+ Mime::XML => :xml_simple,
+ Mime::JSON => :json }
cattr_accessor :relative_url_root
- self.send(:class_variable_set, "@@relative_url_root", ENV['RAILS_RELATIVE_URL_ROOT'])
+ self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
cattr_accessor :default_charset
- self.send(:class_variable_set, "@@default_charset", "utf-8")
+ self.default_charset = "utf-8"
- cattr_reader :protected_instance_variables
- self.send(:class_variable_set, "@@protected_instance_variables", %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
+ # cattr_reader :protected_instance_variables
+ cattr_accessor :protected_instance_variables
+ self.protected_instance_variables = %w(@assigns @performed_redirect @performed_render @variables_added @request_origin @url @parent_controller
@action_name @before_filter_chain_aborted @action_cache_path @_headers @_params
- @_flash @_response))
+ @_flash @_response)
+
+ # Indicates whether or not optimise the generated named
+ # route helper methods
+ cattr_accessor :optimise_named_routes
+ self.optimise_named_routes = true
+
+ cattr_accessor :resources_path_names
+ self.resources_path_names = { :new => 'new', :edit => 'edit' }
+
+ # Controls the resource action separator
+ cattr_accessor :resource_action_separator
+ self.resource_action_separator = "/"
+
+ cattr_accessor :use_accept_header
+ self.use_accept_header = true
+
+ cattr_accessor :page_cache_directory
+ self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
+
+ cattr_reader :cache_store
+
+ cattr_accessor :consider_all_requests_local
+ self.consider_all_requests_local = true
end
module ClassMethods
@@ -37,8 +61,18 @@ module ActionController
def rescue_action(env)
raise env["action_dispatch.rescue.exception"]
end
+
+ # Defines the storage option for cached fragments
+ def cache_store=(store_option)
+ @@cache_store = ActiveSupport::Cache.lookup_store(store_option)
+ end
end
-
+
+ def initialize(*)
+ super
+ @template = _action_view
+ end
+
def render_to_body(options)
if options.is_a?(Hash) && options.key?(:template)
options[:template].sub!(/^\//, '')
@@ -48,6 +82,14 @@ module ActionController
super
end
+
+ def _handle_method_missing
+ method_missing(@_action_name.to_sym)
+ end
+
+ def method_for_action(action_name)
+ super || (respond_to?(:method_missing) && "_handle_method_missing")
+ end
def _layout_for_name(name)
name &&= name.sub(%r{^/?layouts/}, '')
diff --git a/actionpack/lib/action_controller/new_base/hide_actions.rb b/actionpack/lib/action_controller/new_base/hide_actions.rb
index d1857a9169..a29b09a893 100644
--- a/actionpack/lib/action_controller/new_base/hide_actions.rb
+++ b/actionpack/lib/action_controller/new_base/hide_actions.rb
@@ -12,8 +12,8 @@ module ActionController
private
- def respond_to_action?(action_name)
- !hidden_actions.include?(action_name) && (super || respond_to?(:method_missing))
+ def action_method?(action_name)
+ !hidden_actions.include?(action_name) && super
end
module ClassMethods
diff --git a/actionpack/lib/action_controller/new_base/http.rb b/actionpack/lib/action_controller/new_base/http.rb
index f269fe70db..8891a2a8c3 100644
--- a/actionpack/lib/action_controller/new_base/http.rb
+++ b/actionpack/lib/action_controller/new_base/http.rb
@@ -1,3 +1,6 @@
+require 'action_controller/abstract'
+require 'active_support/core_ext/module/delegation'
+
module ActionController
class Http < AbstractController::Base
abstract!
@@ -21,11 +24,6 @@ module ActionController
# :api: public
def controller_path() self.class.controller_path end
- # :api: private
- def self.internal_methods
- ActionController::Http.public_instance_methods(true)
- end
-
# :api: private
def self.action_names() action_methods end
@@ -38,26 +36,32 @@ module ActionController
controller.call(env).to_rack
end
+ delegate :headers, :to => "@_response"
+
+ def params
+ @_params ||= @_request.parameters
+ end
+
# :api: private
def call(name, env)
@_request = ActionDispatch::Request.new(env)
@_response = ActionDispatch::Response.new
@_response.request = request
process(name)
- @_response.body = response_body
- @_response.prepare!
to_rack
end
def self.action(name)
@actions ||= {}
- @actions[name] ||= proc do |env|
+ @actions[name.to_s] ||= proc do |env|
new.call(name, env)
end
end
# :api: private
def to_rack
+ @_response.body = response_body
+ @_response.prepare!
@_response.to_a
end
end
diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb
index e851eb5f9a..bf5b14c4e1 100644
--- a/actionpack/lib/action_controller/new_base/layouts.rb
+++ b/actionpack/lib/action_controller/new_base/layouts.rb
@@ -15,7 +15,7 @@ module ActionController
# render :text => ..., :layout => ...
# or
# render :anything_else
- if (!options.key?(:text) && !options.key?(:inline)) || options.key?(:layout)
+ if (!options.key?(:text) && !options.key?(:inline) && !options.key?(:partial)) || options.key?(:layout)
options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout
end
diff --git a/actionpack/lib/action_controller/new_base/redirector.rb b/actionpack/lib/action_controller/new_base/redirector.rb
new file mode 100644
index 0000000000..ff7b74341c
--- /dev/null
+++ b/actionpack/lib/action_controller/new_base/redirector.rb
@@ -0,0 +1,19 @@
+module ActionController
+ class RedirectBackError < AbstractController::Error #:nodoc:
+ DEFAULT_MESSAGE = 'No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].'
+
+ def initialize(message = nil)
+ super(message || DEFAULT_MESSAGE)
+ end
+ end
+
+ module Redirector
+ def redirect_to(url, status) #:doc:
+ raise AbstractController::DoubleRenderError if response_body
+ logger.info("Redirected to #{url}") if logger && logger.info?
+ response.status = status
+ response.location = url.gsub(/[\r\n]/, '')
+ self.response_body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb
index 41e3dfbe23..8a9f230603 100644
--- a/actionpack/lib/action_controller/new_base/renderer.rb
+++ b/actionpack/lib/action_controller/new_base/renderer.rb
@@ -9,13 +9,9 @@ module ActionController
super
end
- def render(options = {})
+ def render_to_body(options)
_process_options(options)
- super(options)
- end
-
- def render_to_body(options)
if options.key?(:text)
options[:_template] = ActionView::TextTemplate.new(_text(options))
template = nil
@@ -25,12 +21,18 @@ module ActionController
options[:_template] = template
elsif options.key?(:template)
options[:_template_name] = options[:template]
+ elsif options.key?(:file)
+ options[:_template_name] = options[:file]
+ elsif options.key?(:partial)
+ _render_partial(options[:partial], options)
else
options[:_template_name] = (options[:action] || action_name).to_s
options[:_prefix] = _prefix
end
ret = super(options)
+
+ options[:_template] ||= _action_view._partial
response.content_type ||= options[:_template].mime_type
ret
end
@@ -49,6 +51,21 @@ module ActionController
else text.to_s
end
end
+
+ def _render_partial(partial, options)
+ case partial
+ when true
+ options[:_prefix] = _prefix
+ when String
+ options[:_prefix] = _prefix unless partial.index('/')
+ options[:_template_name] = partial
+ else
+ options[:_partial_object] = true
+ return
+ end
+
+ options[:_partial] = options[:object] || true
+ end
def _process_options(options)
status, content_type = options.values_at(:status, :content_type)
diff --git a/actionpack/lib/action_controller/new_base/rescuable.rb b/actionpack/lib/action_controller/new_base/rescuable.rb
new file mode 100644
index 0000000000..29ffe19d5f
--- /dev/null
+++ b/actionpack/lib/action_controller/new_base/rescuable.rb
@@ -0,0 +1,53 @@
+module ActionController #:nodoc:
+ # Actions that fail to perform as expected throw exceptions. These
+ # exceptions can either be rescued for the public view (with a nice
+ # user-friendly explanation) or for the developers view (with tons of
+ # debugging information). The developers view is already implemented by
+ # the Action Controller, but the public view should be tailored to your
+ # specific application.
+ #
+ # The default behavior for public exceptions is to render a static html
+ # file with the name of the error code thrown. If no such file exists, an
+ # empty response is sent with the correct status code.
+ #
+ # You can override what constitutes a local request by overriding the
+ # <tt>local_request?</tt> method in your own controller. Custom rescue
+ # behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
+ # and <tt>rescue_action_locally</tt> methods.
+ module Rescue
+ extend ActiveSupport::DependencyModule
+
+ included do
+ include ActiveSupport::Rescuable
+ end
+
+ module ClassMethods
+ # This can be removed once we can move action(:_rescue_action) into middlewares.rb
+ # Currently, it does controller.method(:rescue_action), which is hiding the implementation
+ # difference between the old and new base.
+ def rescue_action(env)
+ action(:_rescue_action).call(env)
+ end
+ end
+
+ attr_internal :rescued_exception
+
+ private
+
+ def method_for_action(action_name)
+ return action_name if self.rescued_exception = request.env.delete("action_dispatch.rescue.exception")
+ super
+ end
+
+ def _rescue_action
+ rescue_with_handler(rescued_exception) || raise(rescued_exception)
+ end
+
+ def process_action(*)
+ super
+ rescue Exception => exception
+ self.rescued_exception = exception
+ _rescue_action
+ end
+ end
+end
diff --git a/actionpack/lib/action_controller/new_base/testing.rb b/actionpack/lib/action_controller/new_base/testing.rb
index 106990b9ba..b39d8d539d 100644
--- a/actionpack/lib/action_controller/new_base/testing.rb
+++ b/actionpack/lib/action_controller/new_base/testing.rb
@@ -7,7 +7,7 @@ module ActionController
@_response = response
@_response.request = request
ret = process(request.parameters[:action])
- @_response.body = self.response_body
+ @_response.body = self.response_body || " "
@_response.prepare!
set_test_assigns
ret
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index 6bda27e23a..b4408e4e1d 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module'
+
module ActionController
# The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or
# Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate
diff --git a/actionpack/lib/action_controller/routing.rb b/actionpack/lib/action_controller/routing.rb
index c0eb61340b..ce59866531 100644
--- a/actionpack/lib/action_controller/routing.rb
+++ b/actionpack/lib/action_controller/routing.rb
@@ -1,5 +1,9 @@
require 'cgi'
require 'uri'
+require 'set'
+
+require 'active_support/core_ext/module/aliasing'
+require 'active_support/core_ext/module/attribute_accessors'
require 'action_controller/routing/optimisations'
require 'action_controller/routing/routing_ext'
require 'action_controller/routing/route'
diff --git a/actionpack/lib/action_controller/routing/builder.rb b/actionpack/lib/action_controller/routing/builder.rb
index d9590c88b8..42ad12e1ea 100644
--- a/actionpack/lib/action_controller/routing/builder.rb
+++ b/actionpack/lib/action_controller/routing/builder.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/hash/except'
+
module ActionController
module Routing
class RouteBuilder #:nodoc:
diff --git a/actionpack/lib/action_controller/routing/route.rb b/actionpack/lib/action_controller/routing/route.rb
index e2077edad8..eba05a3c5a 100644
--- a/actionpack/lib/action_controller/routing/route.rb
+++ b/actionpack/lib/action_controller/routing/route.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/misc'
+
module ActionController
module Routing
class Route #:nodoc:
@@ -65,7 +67,7 @@ module ActionController
# map.connect '/page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
#
def parameter_shell
- @parameter_shell ||= returning({}) do |shell|
+ @parameter_shell ||= {}.tap do |shell|
requirements.each do |key, requirement|
shell[key] = requirement unless requirement.is_a? Regexp
end
@@ -76,7 +78,7 @@ module ActionController
# includes keys that appear inside the path, and keys that have requirements
# placed upon them.
def significant_keys
- @significant_keys ||= returning([]) do |sk|
+ @significant_keys ||= [].tap do |sk|
segments.each { |segment| sk << segment.key if segment.respond_to? :key }
sk.concat requirements.keys
sk.uniq!
@@ -86,7 +88,7 @@ module ActionController
# Return a hash of key/value pairs representing the keys in the route that
# have defaults, or which are specified by non-regexp requirements.
def defaults
- @defaults ||= returning({}) do |hash|
+ @defaults ||= {}.tap do |hash|
segments.each do |segment|
next unless segment.respond_to? :default
hash[segment.key] = segment.default unless segment.default.nil?
diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb
index 21023ac101..8831ff57e2 100644
--- a/actionpack/lib/action_controller/testing/process.rb
+++ b/actionpack/lib/action_controller/testing/process.rb
@@ -1,4 +1,5 @@
require 'rack/session/abstract/id'
+require 'active_support/core_ext/object/conversions'
module ActionController #:nodoc:
class TestRequest < ActionDispatch::TestRequest #:nodoc:
@@ -131,9 +132,6 @@ module ActionController #:nodoc:
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
build_request_uri(action, parameters)
- @request.env["action_controller.rescue.request"] = @request
- @request.env["action_controller.rescue.response"] = @response
-
Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
env = @request.env
@@ -161,11 +159,13 @@ module ActionController #:nodoc:
alias xhr :xml_http_request
def assigns(key = nil)
- if key.nil?
- @controller.template.assigns
- else
- @controller.template.assigns[key.to_s]
+ assigns = {}
+ @controller.instance_variable_names.each do |ivar|
+ next if ActionController::Base.protected_instance_variables.include?(ivar)
+ assigns[ivar[1..-1]] = @controller.instance_variable_get(ivar)
end
+
+ key.nil? ? assigns : assigns[key.to_s]
end
def session
diff --git a/actionpack/lib/action_controller/testing/process2.rb b/actionpack/lib/action_controller/testing/process2.rb
index 18b7335450..e9a79369b9 100644
--- a/actionpack/lib/action_controller/testing/process2.rb
+++ b/actionpack/lib/action_controller/testing/process2.rb
@@ -50,6 +50,7 @@ module ActionController
@request.session = ActionController::TestSession.new(session) unless session.nil?
@request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
build_request_uri(action, parameters)
+ @controller.request = @request
@controller.params.merge!(parameters)
# Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
@controller.process_with_test(@request, @response)
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
index ae20f9947c..a992f7d912 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -73,7 +73,7 @@ module HTML
# Specifies the default Set of tags that the #sanitize helper will allow unscathed.
self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub
- sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dt dd abbr
+ sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr
acronym a img blockquote del ins))
# Specifies the default Set of html attributes that the #sanitize helper will leave
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index c882930e64..6fc4ad3f21 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -21,16 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-begin
- require 'active_support'
-rescue LoadError
- activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
- if File.directory?(activesupport_path)
- $:.unshift activesupport_path
- require 'active_support'
- end
-end
-require 'active_support/core/all'
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift activesupport_path if File.directory?(activesupport_path)
+require 'active_support'
begin
gem 'rack', '~> 1.1.pre'
@@ -45,7 +38,7 @@ module ActionDispatch
autoload :Response, 'action_dispatch/http/response'
autoload :StatusCodes, 'action_dispatch/http/status_codes'
- autoload :Failsafe, 'action_dispatch/middleware/failsafe'
+ autoload :Callbacks, 'action_dispatch/middleware/callbacks'
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
autoload :Rescue, 'action_dispatch/middleware/rescue'
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 02ad7f7d94..dfcf3a558f 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -1,4 +1,5 @@
require 'set'
+require 'active_support/core_ext/class/attribute_accessors'
module Mime
SET = []
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index e4f3a8f125..13ff049a97 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -3,6 +3,7 @@ require 'stringio'
require 'strscan'
require 'active_support/memoizable'
+require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
class Request < Rack::Request
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 133b4f7335..edb522ff49 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -1,4 +1,5 @@
require 'digest/md5'
+require 'active_support/core_ext/module/delegation'
module ActionDispatch # :nodoc:
# Represents an HTTP response generated by a controller action. One can use
@@ -156,12 +157,6 @@ module ActionDispatch # :nodoc:
end
end
- def redirect(url, status)
- self.status = status
- self.location = url.gsub(/[\r\n]/, '')
- self.body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
- end
-
def sending_file?
headers["Content-Transfer-Encoding"] == "binary"
end
diff --git a/actionpack/lib/action_dispatch/http/status_codes.rb b/actionpack/lib/action_dispatch/http/status_codes.rb
index 830de2a6db..5bac842ec1 100644
--- a/actionpack/lib/action_dispatch/http/status_codes.rb
+++ b/actionpack/lib/action_dispatch/http/status_codes.rb
@@ -1,3 +1,5 @@
+require 'active_support/inflector'
+
module ActionDispatch
module StatusCodes #:nodoc:
STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES.merge({
@@ -16,7 +18,7 @@ module ActionDispatch
# :created or :not_implemented) into its corresponding HTTP status
# code (like 200 or 501).
SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) { |hash, (code, message)|
- hash[message.gsub(/ /, "").underscore.to_sym] = code
+ hash[ActiveSupport::Inflector.underscore(message.gsub(/ /, "")).to_sym] = code
hash
}.freeze
@@ -37,4 +39,4 @@ module ActionDispatch
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
new file mode 100644
index 0000000000..0a2b4cf5f7
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -0,0 +1,40 @@
+module ActionDispatch
+ class Callbacks
+ include ActiveSupport::Callbacks
+ define_callbacks :prepare, :before, :after
+
+ class << self
+ # DEPRECATED
+ alias_method :prepare_dispatch, :prepare
+ alias_method :before_dispatch, :before
+ alias_method :after_dispatch, :after
+ end
+
+ # Add a preparation callback. Preparation callbacks are run before every
+ # request in development mode, and before the first request in production
+ # mode.
+ #
+ # An optional identifier may be supplied for the callback. If provided,
+ # to_prepare may be called again with the same identifier to replace the
+ # existing callback. Passing an identifier is a suggested practice if the
+ # code adding a preparation block may be reloaded.
+ def self.to_prepare(identifier = nil, &block)
+ @prepare_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
+ callback = ActiveSupport::Callbacks::Callback.new(:prepare, block, :identifier => identifier)
+ @prepare_callbacks.replace_or_append!(callback)
+ end
+
+ def initialize(app, prepare_each_request = false)
+ @app, @prepare_each_request = app, prepare_each_request
+ run_callbacks :prepare
+ end
+
+ def call(env)
+ run_callbacks :before
+ run_callbacks :prepare if @prepare_each_request
+ @app.call(env)
+ ensure
+ run_callbacks :after, :enumerator => :reverse_each
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/middleware/failsafe.rb b/actionpack/lib/action_dispatch/middleware/failsafe.rb
deleted file mode 100644
index 836098482c..0000000000
--- a/actionpack/lib/action_dispatch/middleware/failsafe.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module ActionDispatch
- class Failsafe
- cattr_accessor :error_file_path
- self.error_file_path = Rails.public_path if defined?(Rails.public_path)
-
- def initialize(app)
- @app = app
- end
-
- def call(env)
- @app.call(env)
- rescue Exception => exception
- # Reraise exception in test environment
- if defined?(Rails) && Rails.env.test?
- raise exception
- else
- failsafe_response(exception)
- end
- end
-
- private
- def failsafe_response(exception)
- log_failsafe_exception(exception)
- [500, {'Content-Type' => 'text/html'}, failsafe_response_body]
- rescue Exception => failsafe_error # Logger or IO errors
- $stderr.puts "Error during failsafe response: #{failsafe_error}"
- end
-
- def failsafe_response_body
- error_path = "#{self.class.error_file_path}/500.html"
- if File.exist?(error_path)
- [File.read(error_path)]
- else
- ["<html><body><h1>500 Internal Server Error</h1></body></html>"]
- end
- end
-
- def log_failsafe_exception(exception)
- message = "/!\\ FAILSAFE /!\\ #{Time.now}\n Status: 500 Internal Server Error\n"
- message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception
- failsafe_logger.fatal(message)
- end
-
- def failsafe_logger
- if defined?(Rails) && Rails.logger
- Rails.logger
- else
- Logger.new($stderr)
- end
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 58d527a6e7..e83cf9236b 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -32,16 +32,14 @@ module ActionDispatch
when Proc
strategy.call(request.raw_post)
when :xml_simple, :xml_node
- body = request.raw_post
- body.blank? ? {} : Hash.from_xml(body).with_indifferent_access
+ request.body.size == 0 ? {} : Hash.from_xml(request.body).with_indifferent_access
when :yaml
- YAML.load(request.raw_post)
+ YAML.load(request.body)
when :json
- body = request.raw_post
- if body.blank?
+ if request.body.size == 0
{}
else
- data = ActiveSupport::JSON.decode(body)
+ data = ActiveSupport::JSON.decode(request.body)
data = {:_json => data} unless data.is_a?(Hash)
data.with_indifferent_access
end
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index 71c1e1b9a9..108355da63 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -4,8 +4,11 @@ module ActionDispatch
LOCALHOST = '127.0.0.1'.freeze
- DEFAULT_RESCUE_RESPONSE = :internal_server_error
- DEFAULT_RESCUE_RESPONSES = {
+ RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
+
+ cattr_accessor :rescue_responses
+ @@rescue_responses = Hash.new(:internal_server_error)
+ @@rescue_responses.update({
'ActionController::RoutingError' => :not_found,
'ActionController::UnknownAction' => :not_found,
'ActiveRecord::RecordNotFound' => :not_found,
@@ -15,25 +18,19 @@ module ActionDispatch
'ActionController::MethodNotAllowed' => :method_not_allowed,
'ActionController::NotImplemented' => :not_implemented,
'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
- }
+ })
- DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
- DEFAULT_RESCUE_TEMPLATES = {
+ cattr_accessor :rescue_templates
+ @@rescue_templates = Hash.new('diagnostics')
+ @@rescue_templates.update({
'ActionView::MissingTemplate' => 'missing_template',
'ActionController::RoutingError' => 'routing_error',
'ActionController::UnknownAction' => 'unknown_action',
'ActionView::TemplateError' => 'template_error'
- }
-
- RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
-
- cattr_accessor :rescue_responses
- @@rescue_responses = Hash.new(DEFAULT_RESCUE_RESPONSE)
- @@rescue_responses.update DEFAULT_RESCUE_RESPONSES
+ })
- cattr_accessor :rescue_templates
- @@rescue_templates = Hash.new(DEFAULT_RESCUE_TEMPLATE)
- @@rescue_templates.update DEFAULT_RESCUE_TEMPLATES
+ FAILSAFE_RESPONSE = [500, {'Content-Type' => 'text/html'},
+ ['<html><body><h1>500 Internal Server Error</h1></body></html>']]
def initialize(app, consider_all_requests_local = false)
@app = app
@@ -43,34 +40,35 @@ module ActionDispatch
def call(env)
@app.call(env)
rescue Exception => exception
- raise exception if env['rack.test']
+ raise exception if env['action_dispatch.show_exceptions'] == false
+ render_exception(env, exception)
+ end
- log_error(exception) if logger
+ private
+ def render_exception(env, exception)
+ log_error(exception)
- request = Request.new(env)
- if @consider_all_requests_local || local_request?(request)
- rescue_action_locally(request, exception)
- else
- rescue_action_in_public(exception)
+ request = Request.new(env)
+ if @consider_all_requests_local || local_request?(request)
+ rescue_action_locally(request, exception)
+ else
+ rescue_action_in_public(exception)
+ end
+ rescue Exception => failsafe_error
+ $stderr.puts "Error during failsafe response: #{failsafe_error}"
+ FAILSAFE_RESPONSE
end
- end
- private
# Render detailed diagnostics for unhandled exceptions rescued from
# a controller action.
def rescue_action_locally(request, exception)
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
- :template => template,
:request => request,
:exception => exception
)
file = "rescues/#{@@rescue_templates[exception.class.name]}.erb"
body = template.render(:file => file, :layout => 'rescues/layout.erb')
-
- headers = {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}
- status = status_code(exception)
-
- [status, headers, body]
+ render(status_code(exception), body)
end
# Attempts to render a static error page based on the
@@ -86,11 +84,11 @@ module ActionDispatch
path = "#{public_path}/#{status}.html"
if locale_path && File.exist?(locale_path)
- render_public_file(status, locale_path)
+ render(status, File.read(locale_path))
elsif File.exist?(path)
- render_public_file(status, path)
+ render(status, File.read(path))
else
- [status, {'Content-Type' => 'text/html', 'Content-Length' => '0'}, []]
+ render(status, '')
end
end
@@ -99,24 +97,21 @@ module ActionDispatch
request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
end
- def render_public_file(status, path)
- body = File.read(path)
- [status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body]
- end
-
def status_code(exception)
interpret_status(@@rescue_responses[exception.class.name]).to_i
end
+ def render(status, body)
+ [status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body]
+ end
+
def public_path
- if defined?(Rails)
- Rails.public_path
- else
- "public"
- end
+ defined?(Rails.public_path) ? Rails.public_path : 'public_path'
end
- def log_error(exception) #:doc:
+ def log_error(exception)
+ return unless logger
+
ActiveSupport::Deprecation.silence do
if ActionView::TemplateError === exception
logger.fatal(exception.to_s)
@@ -136,9 +131,7 @@ module ActionDispatch
end
def logger
- if defined?(Rails.logger)
- Rails.logger
- end
+ defined?(Rails.logger) ? Rails.logger : Logger.new($stderr)
end
end
end
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index dd352f9ce0..94138097e3 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -21,16 +21,10 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-begin
- require 'active_support'
-rescue LoadError
- activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
- if File.directory?(activesupport_path)
- $:.unshift activesupport_path
- require 'active_support'
- end
-end
-require 'active_support/core/all'
+activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
+$:.unshift activesupport_path if File.directory?(activesupport_path)
+require 'active_support'
+require 'active_support/core_ext/class/attribute_accessors'
require File.join(File.dirname(__FILE__), "action_pack")
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 44bd401631..56f0b5ef4f 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/module/attr_internal'
+require 'active_support/core_ext/module/delegation'
+
module ActionView #:nodoc:
class ActionViewError < StandardError #:nodoc:
end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index a59829b23f..beef661a37 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -2,6 +2,7 @@ require 'cgi'
require 'action_view/helpers/date_helper'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/form_tag_helper'
+require 'active_support/core_ext/class/inheritable_attributes'
module ActionView
module Helpers
@@ -1039,8 +1040,8 @@ module ActionView
end
end
- class Base
- cattr_accessor :default_form_builder
- self.default_form_builder = ::ActionView::Helpers::FormBuilder
+ class << Base
+ attr_accessor :default_form_builder
end
-end \ No newline at end of file
+ Base.default_form_builder = ::ActionView::Helpers::FormBuilder
+end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 6b385ef77d..6adbab175f 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -230,6 +230,8 @@ module ActionView
#
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def options_for_select(container, selected = nil)
+ return container if String === container
+
container = container.to_a if Hash === container
selected, disabled = extract_selected_and_disabled(selected)
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index c02692b09a..999d5b34fc 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -248,6 +248,11 @@ module ActionView
# number_to_human_size(483989, :precision => 0) # => 473 KB
# number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB
#
+ # Zeros after the decimal point are always stripped out, regardless of the
+ # specified precision:
+ # helper.number_to_human_size(1234567890123, :precision => 5) # => "1.12283 TB"
+ # helper.number_to_human_size(524288000, :precision=>5) # => "500 MB"
+ #
# You can still use <tt>number_to_human_size</tt> with the old API that accepts the
# +precision+ as its optional second parameter:
# number_to_human_size(1234567, 2) # => 1.18 MB
@@ -293,7 +298,7 @@ module ActionView
:precision => precision,
:separator => separator,
:delimiter => delimiter
- ).sub(/(\d)(#{escaped_separator}[1-9]*)?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
+ ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
rescue
number
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index af8c4d5e21..66d7592874 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -9,7 +9,7 @@ module ActionView
include ERB::Util
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked).to_set
- BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
+ BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attr| attr.to_sym })
# Returns an empty HTML tag of type +name+ which by default is XHTML
# compliant. Set +open+ to true to create an open tag compatible
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 573b99b96e..8136a1cb13 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -535,7 +535,7 @@ module ActionView
link_attributes = html_options.stringify_keys
text.gsub(AUTO_LINK_RE) do
href = $&
- punctuation = ''
+ punctuation = []
left, right = $`, $'
# detect already linked URLs and URLs in the middle of a tag
if left =~ /<[^>]+$/ && right =~ /^[^>]*>/
@@ -543,17 +543,18 @@ module ActionView
href
else
# don't include trailing punctuation character as part of the URL
- if href.sub!(/[^\w\/-]$/, '') and punctuation = $& and opening = BRACKETS[punctuation]
- if href.scan(opening).size > href.scan(punctuation).size
- href << punctuation
- punctuation = ''
+ while href.sub!(/[^\w\/-]$/, '')
+ punctuation.push $&
+ if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
+ href << punctuation.pop
+ break
end
end
link_text = block_given?? yield(href) : href
href = 'http://' + href unless href.index('http') == 0
- content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation
+ content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation.reverse.join('')
end
end
end
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index 43f8a1edf8..f2429e8cef 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -171,11 +171,21 @@ module ActionView
# <% end %>
module Partials
extend ActiveSupport::Memoizable
+ extend ActiveSupport::DependencyModule
+
+ included do
+ attr_accessor :_partial
+ end
+
+ def _render_partial_from_controller(*args)
+ @assigns_added = false
+ _render_partial(*args)
+ end
def _render_partial(options = {}) #:nodoc:
options[:locals] ||= {}
- case path = partial = options[:partial]
+ case path = partial = options[:partial]
when *_array_like_objects
return _render_partial_collection(partial, options)
else
@@ -222,16 +232,7 @@ module ActionView
ensure
@_proc_for_layout = nil
end
-
- def _render_partial_with_layout(layout, options)
- if layout
- prefix = controller && !layout.include?("/") ? controller.controller_path : nil
- layout = find_by_parts(layout, {:formats => formats}, prefix, true)
- end
- content = _render_partial(options)
- return _render_content_with_layout(content, layout, options[:locals])
- end
-
+
def _deprecated_ivar_assign(template)
if respond_to?(:controller)
ivar = :"@#{template.variable_name}"
@@ -287,13 +288,17 @@ module ActionView
locals = (options[:locals] ||= {})
object ||= locals[:object] || locals[template.variable_name]
- _set_locals(object, locals, template, options)
+ _set_locals(object, locals, template, options)
+
+ self._partial = template
+
_render_template(template, locals)
end
end
def _set_locals(object, locals, template, options)
object ||= _deprecated_ivar_assign(template)
+
locals[:object] = locals[template.variable_name] = object
locals[options[:as]] = object if options[:as]
end
@@ -316,6 +321,9 @@ module ActionView
locals[template.counter_name] = index
index += 1
+
+ self._partial = template
+
_render_template(template, locals)
end.join(spacer)
end
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index 6e368f27eb..fe785e7b20 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -95,6 +95,11 @@ module ActionView
layout ? _render_content_with_layout(text, layout, options[:locals]) : text
end
+ def _render_template_from_controller(*args)
+ @assigns_added = nil
+ _render_template_with_layout(*args)
+ end
+
def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
if controller && logger
logger.info("Rendering #{template.identifier}" +
diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb
index 0590372d09..faf54b9fe5 100644
--- a/actionpack/lib/action_view/template/handlers.rb
+++ b/actionpack/lib/action_view/template/handlers.rb
@@ -33,7 +33,7 @@ module ActionView #:nodoc:
end
def template_handler_extensions
- @@template_handlers.keys.map(&:to_s).sort
+ @@template_handlers.keys.map {|key| key.to_s }.sort
end
def registered_template_handler(extension)
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index a20b1b0cd3..fdcb108ffc 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -1,4 +1,5 @@
require 'erb'
+require 'active_support/core_ext/class/attribute_accessors'
module ActionView
module TemplateHandlers
diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb
index 689aa99fd8..9c028e7d1e 100644
--- a/actionpack/test/abstract_controller/abstract_controller_test.rb
+++ b/actionpack/test/abstract_controller/abstract_controller_test.rb
@@ -201,11 +201,10 @@ module AbstractController
def fail() self.response_body = "fail" end
private
-
- def respond_to_action?(action_name)
- action_name.to_s != "fail"
+
+ def method_for_action(action_name)
+ action_name.to_s != "fail" && action_name
end
-
end
class TestRespondToAction < ActiveSupport::TestCase
diff --git a/actionpack/test/abstract_controller/callbacks_test.rb b/actionpack/test/abstract_controller/callbacks_test.rb
index 410b1e57a6..1de60868c3 100644
--- a/actionpack/test/abstract_controller/callbacks_test.rb
+++ b/actionpack/test/abstract_controller/callbacks_test.rb
@@ -193,5 +193,24 @@ module AbstractController
end
end
+ class SetsResponseBody < ControllerWithCallbacks
+ before_filter :set_body
+
+ def index
+ self.response_body = "Fail"
+ end
+
+ def set_body
+ self.response_body = "Success"
+ end
+ end
+
+ class TestHalting < ActiveSupport::TestCase
+ test "when a callback sets the response body, the action should not be invoked" do
+ result = SetsResponseBody.process(:index)
+ assert_equal "Success", result.response_body
+ end
+ end
+
end
end \ No newline at end of file
diff --git a/actionpack/test/abstract_controller/test_helper.rb b/actionpack/test/abstract_controller/test_helper.rb
index a08ab5a6d7..915054f7fb 100644
--- a/actionpack/test/abstract_controller/test_helper.rb
+++ b/actionpack/test/abstract_controller/test_helper.rb
@@ -4,7 +4,7 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
require 'rubygems'
require 'test/unit'
-require 'active_support/core/all'
+require 'active_support'
require 'active_support/test_case'
require 'action_controller/abstract'
require 'action_view'
@@ -18,4 +18,4 @@ begin
Debugger.start
rescue LoadError
# Debugging disabled. `gem install ruby-debug` to enable.
-end \ No newline at end of file
+end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index b07e6e5f3a..7982f06545 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -1,3 +1,6 @@
+if ENV["new_base"]
+ require "abstract_unit2"
+else
$:.unshift(File.dirname(__FILE__) + '/../lib')
$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
@@ -34,7 +37,8 @@ ActionController::Base.session_store = nil
# Register danish language for testing
I18n.backend.store_translations 'da', {}
I18n.backend.store_translations 'pt-BR', {}
-ORIGINAL_LOCALES = I18n.available_locales.map(&:to_s).sort
+ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
ActionController::Base.view_paths = FIXTURE_LOAD_PATH
+end \ No newline at end of file
diff --git a/actionpack/test/abstract_unit2.rb b/actionpack/test/abstract_unit2.rb
index 95e7b2e273..519e6bea36 100644
--- a/actionpack/test/abstract_unit2.rb
+++ b/actionpack/test/abstract_unit2.rb
@@ -5,18 +5,25 @@ $:.unshift(File.dirname(__FILE__) + '/lib')
require 'test/unit'
require 'active_support'
-require 'active_support/core/all'
require 'active_support/test_case'
require 'action_controller/abstract'
require 'action_controller/new_base'
require 'fixture_template'
require 'action_controller/testing/process2'
require 'action_view/test_case'
+require 'action_controller/testing/integration'
+require 'active_support/dependencies'
+
+ActiveSupport::Dependencies.hook!
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
module ActionController
-
+ Base.session = {
+ :key => '_testing_session',
+ :secret => '8273f16463985e2b3747dc25e30f2528'
+}
+
class ActionControllerError < StandardError #:nodoc:
end
@@ -75,7 +82,7 @@ module ActionController
end
class Base
- use ActionController::Testing
+ include ActionController::Testing
end
Base.view_paths = FIXTURE_LOAD_PATH
@@ -89,45 +96,44 @@ module ActionController
end
def assert_template(options = {}, message = nil)
- validate_response!
-
- clean_backtrace do
- case options
- when NilClass, String
- hax = @controller._action_view.instance_variable_get(:@_rendered)
- rendered = (hax[:template] || []).map { |t| t.identifier }
- msg = build_message(message,
- "expecting <?> but rendering with <?>",
- options, rendered.join(', '))
- assert_block(msg) do
- if options.nil?
- hax[:template].blank?
- else
- rendered.any? { |t| t.match(options) }
- end
+ validate_request!
+
+ hax = @controller._action_view.instance_variable_get(:@_rendered)
+
+ case options
+ when NilClass, String
+ rendered = (hax[:template] || []).map { |t| t.identifier }
+ msg = build_message(message,
+ "expecting <?> but rendering with <?>",
+ options, rendered.join(', '))
+ assert_block(msg) do
+ if options.nil?
+ hax[:template].blank?
+ else
+ rendered.any? { |t| t.match(options) }
end
- when Hash
- if expected_partial = options[:partial]
- partials = hax[:partials]
- if expected_count = options[:count]
- found = partials.detect { |p, _| p.identifier.match(expected_partial) }
- actual_count = found.nil? ? 0 : found.second
- msg = build_message(message,
- "expecting ? to be rendered ? time(s) but rendered ? time(s)",
- expected_partial, expected_count, actual_count)
- assert(actual_count == expected_count.to_i, msg)
- else
- msg = build_message(message,
- "expecting partial <?> but action rendered <?>",
- options[:partial], partials.keys)
- assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
- end
+ end
+ when Hash
+ if expected_partial = options[:partial]
+ partials = hax[:partials]
+ if expected_count = options[:count]
+ found = partials.detect { |p, _| p.identifier.match(expected_partial) }
+ actual_count = found.nil? ? 0 : found.second
+ msg = build_message(message,
+ "expecting ? to be rendered ? time(s) but rendered ? time(s)",
+ expected_partial, expected_count, actual_count)
+ assert(actual_count == expected_count.to_i, msg)
else
- assert hax[:partials].empty?,
- "Expected no partials to be rendered"
+ msg = build_message(message,
+ "expecting partial <?> but action rendered <?>",
+ options[:partial], partials.keys)
+ assert(partials.keys.any? { |p| p.identifier.match(expected_partial) }, msg)
end
+ else
+ assert hax[:partials].empty?,
+ "Expected no partials to be rendered"
end
end
- end
+ end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/test/activerecord/active_record_store_test.rb b/actionpack/test/activerecord/active_record_store_test.rb
index 663cd259c8..47f8496181 100644
--- a/actionpack/test/activerecord/active_record_store_test.rb
+++ b/actionpack/test/activerecord/active_record_store_test.rb
@@ -28,9 +28,9 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
end
def call_reset_session
- session[:bar]
+ session[:foo]
reset_session
- session[:bar] = "baz"
+ session[:foo] = "baz"
head :ok
end
@@ -91,7 +91,7 @@ class ActiveRecordStoreTest < ActionController::IntegrationTest
get '/get_session_value'
assert_response :success
- assert_equal 'foo: nil', response.body
+ assert_equal 'foo: "baz"', response.body
get '/get_session_id'
assert_response :success
diff --git a/actionpack/test/activerecord/polymorphic_routes_test.rb b/actionpack/test/activerecord/polymorphic_routes_test.rb
index 35139fbb7f..b9f5be2361 100644
--- a/actionpack/test/activerecord/polymorphic_routes_test.rb
+++ b/actionpack/test/activerecord/polymorphic_routes_test.rb
@@ -1,4 +1,5 @@
require 'active_record_unit'
+require 'fixtures/project'
class Task < ActiveRecord::Base
set_table_name 'projects'
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
index 484d3c5ce7..c3c769919a 100644
--- a/actionpack/test/controller/action_pack_assertions_test.rb
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -12,6 +12,9 @@ class ActionPackAssertionsController < ActionController::Base
# a standard template
def hello_xml_world() render :template => "test/hello_xml_world"; end
+ # a standard partial
+ def partial() render :partial => 'test/partial'; end
+
# a redirect to an internal location
def redirect_internal() redirect_to "/nothing"; end
@@ -331,6 +334,26 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
end
end
+ def test_assert_template_with_partial
+ get :partial
+ assert_template :partial => '_partial'
+ end
+
+ def test_assert_template_with_nil
+ get :nothing
+ assert_template nil
+ end
+
+ def test_assert_template_with_string
+ get :hello_world
+ assert_template 'hello_world'
+ end
+
+ def test_assert_template_with_symbol
+ get :hello_world
+ assert_template :hello_world
+ end
+
# check if we were rendered by a file-based template?
def test_rendered_action
process :nothing
diff --git a/actionpack/test/controller/addresses_render_test.rb b/actionpack/test/controller/addresses_render_test.rb
index 2f092b6731..2d2a2745b0 100644
--- a/actionpack/test/controller/addresses_render_test.rb
+++ b/actionpack/test/controller/addresses_render_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'logger'
class Address
def Address.count(conditions = nil, join = nil)
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 0c54d61426..3a4cdb81d9 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'logger'
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late
# Provide some controller to run the tests on.
@@ -116,7 +117,7 @@ class PerformActionTest < ActionController::TestCase
end
def method_missing(method, *args)
- @logged << args.first
+ @logged << args.first.to_s
end
end
diff --git a/actionpack/test/controller/capture_test.rb b/actionpack/test/controller/capture_test.rb
index 9a0976ca9f..06a5af6b32 100644
--- a/actionpack/test/controller/capture_test.rb
+++ b/actionpack/test/controller/capture_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'logger'
class CaptureController < ActionController::Base
def self.controller_name; "test"; end
diff --git a/actionpack/test/controller/dispatcher_test.rb b/actionpack/test/controller/dispatcher_test.rb
index b315232a7b..9fae1fcf63 100644
--- a/actionpack/test/controller/dispatcher_test.rb
+++ b/actionpack/test/controller/dispatcher_test.rb
@@ -6,20 +6,20 @@ class DispatcherTest < Test::Unit::TestCase
def setup
ENV['REQUEST_METHOD'] = 'GET'
- Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
- middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
- middleware.instance_eval(File.read(middlewares))
- end
-
# Clear callbacks as they are redefined by Dispatcher#define_dispatcher_callbacks
- Dispatcher.instance_variable_set("@prepare_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
- Dispatcher.instance_variable_set("@before_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
- Dispatcher.instance_variable_set("@after_dispatch_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@prepare_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@before_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ ActionDispatch::Callbacks.instance_variable_set("@after_callbacks", ActiveSupport::Callbacks::CallbackChain.new)
+ @old_router, Dispatcher.router = Dispatcher.router, mock()
+ Dispatcher.router.stubs(:call).returns([200, {}, 'response'])
+ Dispatcher.router.stubs(:reload)
Dispatcher.stubs(:require_dependency)
end
def teardown
+ Dispatcher.router = @old_router
+ @dispatcher = nil
ENV.delete 'REQUEST_METHOD'
end
@@ -29,12 +29,12 @@ class DispatcherTest < Test::Unit::TestCase
end
def test_reloads_routes_before_dispatch_if_in_loading_mode
- ActionController::Routing::Routes.expects(:reload).once
+ Dispatcher.router.expects(:reload).once
dispatch(false)
end
def test_leaves_dependencies_after_dispatch_if_not_in_loading_mode
- ActionController::Routing::Routes.expects(:reload).never
+ Dispatcher.router.expects(:reload).never
ActiveSupport::Dependencies.expects(:clear).never
dispatch
@@ -55,7 +55,7 @@ class DispatcherTest < Test::Unit::TestCase
assert_nil a || b || c
# Run callbacks
- Dispatcher.run_prepare_callbacks
+ dispatch
assert_equal 1, a
assert_equal 2, b
@@ -72,16 +72,22 @@ class DispatcherTest < Test::Unit::TestCase
Dispatcher.to_prepare(:unique_id) { |*args| a = b = 1 }
Dispatcher.to_prepare(:unique_id) { |*args| a = 2 }
- Dispatcher.run_prepare_callbacks
+ dispatch
assert_equal 2, a
assert_equal nil, b
end
private
def dispatch(cache_classes = true)
- ActionController::Routing::RouteSet.any_instance.stubs(:call).returns([200, {}, 'response'])
+ ActionController::Dispatcher.prepare_each_request = false
Dispatcher.define_dispatcher_callbacks(cache_classes)
- Dispatcher.new.call({'rack.input' => StringIO.new('')})
+ Dispatcher.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
+ middlewares = File.expand_path(File.join(File.dirname(__FILE__), "../../lib/action_controller/dispatch/middlewares.rb"))
+ middleware.instance_eval(File.read(middlewares))
+ end
+
+ @dispatcher ||= Dispatcher.new
+ @dispatcher.call({'rack.input' => StringIO.new(''), 'action_dispatch.show_exceptions' => false})
end
def assert_subclasses(howmany, klass, message = klass.subclasses.inspect)
diff --git a/actionpack/test/controller/filters_test.rb b/actionpack/test/controller/filters_test.rb
index 9ad49e9282..afefc6a77e 100644
--- a/actionpack/test/controller/filters_test.rb
+++ b/actionpack/test/controller/filters_test.rb
@@ -607,7 +607,6 @@ class FilterTest < Test::Unit::TestCase
def test_dynamic_dispatch
%w(foo bar baz).each do |action|
request = ActionController::TestRequest.new
- request.env["action_controller.rescue.request"] = request
request.query_parameters[:choose] = action
response = DynamicDispatchController.action.call(request.env).last
assert_equal action, response.body
diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb
index 19cd5f4db2..3bbda9eb3a 100644
--- a/actionpack/test/controller/helper_test.rb
+++ b/actionpack/test/controller/helper_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/core_ext/kernel/reporting'
ActionController::Base.helpers_dir = File.dirname(__FILE__) + '/../fixtures/helpers'
@@ -103,7 +104,6 @@ class HelperTest < Test::Unit::TestCase
def call_controller(klass, action)
request = ActionController::TestRequest.new
- request.env["action_controller.rescue.request"] = request
klass.action(action).call(request.env)
end
@@ -111,7 +111,6 @@ class HelperTest < Test::Unit::TestCase
assert_equal 'hello: Iz guuut!',
call_controller(Fun::GamesController, "render_hello_world").last.body
# request = ActionController::TestRequest.new
- # request.env["action_controller.rescue.request"] = request
#
# resp = Fun::GamesController.action(:render_hello_world).call(request.env)
# assert_equal 'hello: Iz guuut!', resp.last.body
@@ -216,7 +215,6 @@ class IsolatedHelpersTest < Test::Unit::TestCase
def call_controller(klass, action)
request = ActionController::TestRequest.new
- request.env["action_controller.rescue.request"] = request
klass.action(action).call(request.env)
end
diff --git a/actionpack/test/controller/render_js_test.rb b/actionpack/test/controller/render_js_test.rb
new file mode 100644
index 0000000000..7b50242910
--- /dev/null
+++ b/actionpack/test/controller/render_js_test.rb
@@ -0,0 +1,37 @@
+require 'abstract_unit'
+require 'controller/fake_models'
+require 'pathname'
+
+class TestController < ActionController::Base
+ protect_from_forgery
+
+ def render_vanilla_js_hello
+ render :js => "alert('hello')"
+ end
+
+ def greeting
+ # let's just rely on the template
+ end
+
+ def partial
+ render :partial => 'partial'
+ end
+end
+
+class RenderTest < ActionController::TestCase
+ def test_render_vanilla_js
+ get :render_vanilla_js_hello
+ assert_equal "alert('hello')", @response.body
+ assert_equal "text/javascript", @response.content_type
+ end
+
+ def test_render_with_default_from_accept_header
+ xhr :get, :greeting
+ assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
+ end
+
+ def test_should_render_js_partial
+ xhr :get, :partial, :format => 'js'
+ assert_equal 'partial js', @response.body
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/render_json_test.rb b/actionpack/test/controller/render_json_test.rb
new file mode 100644
index 0000000000..233b2dfd89
--- /dev/null
+++ b/actionpack/test/controller/render_json_test.rb
@@ -0,0 +1,80 @@
+require 'abstract_unit'
+require 'controller/fake_models'
+require 'pathname'
+
+class TestController < ActionController::Base
+ protect_from_forgery
+
+ def render_json_nil
+ render :json => nil
+ end
+
+ def render_json_hello_world
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
+ end
+
+ def render_json_hello_world_with_callback
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
+ end
+
+ def render_json_with_custom_content_type
+ render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
+ end
+
+ def render_symbol_json
+ render :json => ActiveSupport::JSON.encode(:hello => 'world')
+ end
+
+ def render_json_with_render_to_string
+ render :json => {:hello => render_to_string(:partial => 'partial')}
+ end
+end
+
+class RenderTest < ActionController::TestCase
+ tests TestController
+
+ def setup
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+ # a more accurate simulation of what happens in "real life".
+ super
+ @controller.logger = Logger.new(nil)
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_render_json_nil
+ get :render_json_nil
+ assert_equal 'null', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
+ def test_render_json
+ get :render_json_hello_world
+ assert_equal '{"hello":"world"}', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
+ def test_render_json_with_callback
+ get :render_json_hello_world_with_callback
+ assert_equal 'alert({"hello":"world"})', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
+ def test_render_json_with_custom_content_type
+ get :render_json_with_custom_content_type
+ assert_equal '{"hello":"world"}', @response.body
+ assert_equal 'text/javascript', @response.content_type
+ end
+
+ def test_render_symbol_json
+ get :render_symbol_json
+ assert_equal '{"hello":"world"}', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+
+ def test_render_json_with_render_to_string
+ get :render_json_with_render_to_string
+ assert_equal '{"hello":"partial html"}', @response.body
+ assert_equal 'application/json', @response.content_type
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/render_other_test.rb b/actionpack/test/controller/render_other_test.rb
new file mode 100644
index 0000000000..ddbdd2d213
--- /dev/null
+++ b/actionpack/test/controller/render_other_test.rb
@@ -0,0 +1,222 @@
+require 'abstract_unit'
+require 'controller/fake_models'
+require 'pathname'
+
+class TestController < ActionController::Base
+ protect_from_forgery
+
+ module RenderTestHelper
+ def rjs_helper_method_from_module
+ page.visual_effect :highlight
+ end
+ end
+
+ helper RenderTestHelper
+ helper do
+ def rjs_helper_method(value)
+ page.visual_effect :highlight, value
+ end
+ end
+
+ def enum_rjs_test
+ render :update do |page|
+ page.select('.product').each do |value|
+ page.rjs_helper_method_from_module
+ page.rjs_helper_method(value)
+ page.sortable(value, :url => { :action => "order" })
+ page.draggable(value)
+ end
+ end
+ end
+
+ def render_explicit_html_template
+ end
+
+ def render_custom_code_rjs
+ render :update, :status => 404 do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+
+ def render_implicit_html_template
+ end
+
+ def render_js_with_explicit_template
+ @project_id = 4
+ render :template => 'test/delete_with_js'
+ end
+
+ def render_js_with_explicit_action_template
+ @project_id = 4
+ render :action => 'delete_with_js'
+ end
+
+ def delete_with_js
+ @project_id = 4
+ end
+
+ def update_page
+ render :update do |page|
+ page.replace_html 'balance', '$37,000,000.00'
+ page.visual_effect :highlight, 'balance'
+ end
+ end
+
+ def update_page_with_instance_variables
+ @money = '$37,000,000.00'
+ @div_id = 'balance'
+ render :update do |page|
+ page.replace_html @div_id, @money
+ page.visual_effect :highlight, @div_id
+ end
+ end
+
+ def update_page_with_view_method
+ render :update do |page|
+ page.replace_html 'person', pluralize(2, 'person')
+ end
+ end
+
+ def partial_as_rjs
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+
+ def respond_to_partial_as_rjs
+ respond_to do |format|
+ format.js do
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+ end
+ end
+
+ def render_alternate_default
+ # For this test, the method "default_render" is overridden:
+ @alternate_default_render = lambda do
+ render :update do |page|
+ page.replace :foo, :partial => 'partial'
+ end
+ end
+ end
+
+private
+ def determine_layout
+ case action_name
+ when "render_js_with_explicit_template",
+ "render_js_with_explicit_action_template",
+ "delete_with_js", "update_page", "update_page_with_instance_variables"
+
+ "layouts/standard"
+ when "action_talk_to_layout", "layout_overriding_layout"
+ "layouts/talk_from_action"
+ when "render_implicit_html_template_from_xhr_request"
+ (request.xhr? ? 'layouts/xhr' : 'layouts/standard')
+ end
+ end
+end
+
+class RenderTest < ActionController::TestCase
+ tests TestController
+
+ def setup
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+ # a more accurate simulation of what happens in "real life".
+ super
+ @controller.logger = Logger.new(nil)
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_enum_rjs_test
+ ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
+ get :enum_rjs_test
+ body = %{
+ $$(".product").each(function(value, index) {
+ new Effect.Highlight(element,{});
+ new Effect.Highlight(value,{});
+ Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
+ new Draggable(value, {});
+ });
+ }.gsub(/^ /, '').strip
+ assert_equal body, @response.body
+ end
+
+ def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
+ [:js, "js"].each do |format|
+ assert_nothing_raised do
+ get :render_explicit_html_template, :format => format
+ assert_equal %(document.write("Hello world\\n");), @response.body
+ end
+ end
+ end
+
+ def test_render_custom_code_rjs
+ get :render_custom_code_rjs
+ assert_response 404
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_render_in_an_rjs_template_should_pick_html_templates_when_available
+ [:js, "js"].each do |format|
+ assert_nothing_raised do
+ get :render_implicit_html_template, :format => format
+ assert_equal %(document.write("Hello world\\n");), @response.body
+ end
+ end
+ end
+
+ def test_render_rjs_template_explicitly
+ get :render_js_with_explicit_template
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_rendering_rjs_action_explicitly
+ get :render_js_with_explicit_action_template
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_render_rjs_with_default
+ get :delete_with_js
+ assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
+ end
+
+ def test_update_page
+ get :update_page
+ assert_template nil
+ assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
+ assert_equal 2, @response.body.split($/).length
+ end
+
+ def test_update_page_with_instance_variables
+ get :update_page_with_instance_variables
+ assert_template nil
+ assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
+ assert_match /balance/, @response.body
+ assert_match /\$37/, @response.body
+ end
+
+ def test_update_page_with_view_method
+ get :update_page_with_view_method
+ assert_template nil
+ assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
+ assert_match /2 people/, @response.body
+ end
+
+ def test_should_render_html_formatted_partial_with_rjs
+ xhr :get, :partial_as_rjs
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_should_render_html_formatted_partial_with_rjs_and_js_format
+ xhr :get, :respond_to_partial_as_rjs
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+
+ def test_should_render_with_alternate_default_render
+ xhr :get, :render_alternate_default
+ assert_equal %(Element.replace("foo", "partial html");), @response.body
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index a58d9b08b5..a750f018b8 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1,4 +1,4 @@
-require ENV['new_base'] ? 'abstract_unit2' : 'abstract_unit'
+require 'abstract_unit'
require 'controller/fake_models'
require 'pathname'
@@ -145,18 +145,21 @@ class TestController < ActionController::Base
render :layout => false
end
+ # :ported:
def render_file_with_instance_variables
@secret = 'in the sauce'
path = File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb')
render :file => path
end
+ # :ported:
def render_file_as_string_with_instance_variables
@secret = 'in the sauce'
path = File.expand_path(File.join(File.dirname(__FILE__), '../fixtures/test/render_file_with_ivar.erb'))
render path
end
+ # :ported:
def render_file_not_using_full_path
@secret = 'in the sauce'
render :file => 'test/render_file_with_ivar'
@@ -203,41 +206,11 @@ class TestController < ActionController::Base
render :inline => "<%= controller_name %>"
end
- def render_json_nil
- render :json => nil
- end
-
- def render_json_hello_world
- render :json => ActiveSupport::JSON.encode(:hello => 'world')
- end
-
- def render_json_hello_world_with_callback
- render :json => ActiveSupport::JSON.encode(:hello => 'world'), :callback => 'alert'
- end
-
- def render_json_with_custom_content_type
- render :json => ActiveSupport::JSON.encode(:hello => 'world'), :content_type => 'text/javascript'
- end
-
- def render_symbol_json
- render :json => ActiveSupport::JSON.encode(:hello => 'world')
- end
-
- def render_json_with_render_to_string
- render :json => {:hello => render_to_string(:partial => 'partial')}
- end
-
# :ported:
def render_custom_code
render :text => "hello world", :status => 404
end
- def render_custom_code_rjs
- render :update, :status => 404 do |page|
- page.replace :foo, :partial => 'partial'
- end
- end
-
# :ported:
def render_text_with_nil
render :text => nil
@@ -253,10 +226,6 @@ class TestController < ActionController::Base
render :text => "appended"
end
- def render_vanilla_js_hello
- render :js => "alert('hello')"
- end
-
# This test is testing 3 things:
# render :file in AV :ported:
# render :template in AC :ported:
@@ -271,10 +240,6 @@ class TestController < ActionController::Base
render "test/hello"
end
- def render_xml_with_custom_content_type
- render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
- end
-
def render_line_offset
render :inline => '<% raise %>', :locals => {:foo => 'bar'}
end
@@ -297,6 +262,7 @@ class TestController < ActionController::Base
render :action => "hello_world"
end
+ # :ported:
def builder_layout_test
render :action => "hello", :layout => "layouts/builder"
end
@@ -306,6 +272,7 @@ class TestController < ActionController::Base
render :action => "hello_world_container"
end
+ # :ported:
def partials_list
@test_unchanged = 'hello'
@customers = [ Customer.new("david"), Customer.new("mary") ]
@@ -331,12 +298,6 @@ class TestController < ActionController::Base
:locals => { :local_name => name }
end
- def render_implicit_html_template
- end
-
- def render_explicit_html_template
- end
-
def render_implicit_html_template_from_xhr_request
end
@@ -470,66 +431,6 @@ class TestController < ActionController::Base
render :template => "test/hello_world_from_rxml.builder"
end
- module RenderTestHelper
- def rjs_helper_method_from_module
- page.visual_effect :highlight
- end
- end
-
- helper RenderTestHelper
- helper do
- def rjs_helper_method(value)
- page.visual_effect :highlight, value
- end
- end
-
- def enum_rjs_test
- render :update do |page|
- page.select('.product').each do |value|
- page.rjs_helper_method_from_module
- page.rjs_helper_method(value)
- page.sortable(value, :url => { :action => "order" })
- page.draggable(value)
- end
- end
- end
-
- def delete_with_js
- @project_id = 4
- end
-
- def render_js_with_explicit_template
- @project_id = 4
- render :template => 'test/delete_with_js'
- end
-
- def render_js_with_explicit_action_template
- @project_id = 4
- render :action => 'delete_with_js'
- end
-
- def update_page
- render :update do |page|
- page.replace_html 'balance', '$37,000,000.00'
- page.visual_effect :highlight, 'balance'
- end
- end
-
- def update_page_with_instance_variables
- @money = '$37,000,000.00'
- @div_id = 'balance'
- render :update do |page|
- page.replace_html @div_id, @money
- page.visual_effect :highlight, @div_id
- end
- end
-
- def update_page_with_view_method
- render :update do |page|
- page.replace_html 'person', pluralize(2, 'person')
- end
- end
-
def action_talk_to_layout
# Action template sets variable that's picked up by layout
end
@@ -573,25 +474,6 @@ class TestController < ActionController::Base
head :forbidden, :x_custom_header => "something"
end
- def render_with_location
- render :xml => "<hello/>", :location => "http://example.com", :status => 201
- end
-
- def render_with_object_location
- customer = Customer.new("Some guy", 1)
- render :xml => "<customer/>", :location => customer_url(customer), :status => :created
- end
-
- def render_with_to_xml
- to_xmlable = Class.new do
- def to_xml
- "<i-am-xml/>"
- end
- end.new
-
- render :xml => to_xmlable
- end
-
def render_using_layout_around_block
render :action => "using_layout_around_block"
end
@@ -608,22 +490,6 @@ class TestController < ActionController::Base
render :partial => 'partial.html.erb'
end
- def partial_as_rjs
- render :update do |page|
- page.replace :foo, :partial => 'partial'
- end
- end
-
- def respond_to_partial_as_rjs
- respond_to do |format|
- format.js do
- render :update do |page|
- page.replace :foo, :partial => 'partial'
- end
- end
- end
- end
-
def partial
render :partial => 'partial'
end
@@ -880,82 +746,54 @@ class RenderTest < ActionController::TestCase
assert_equal 'Hello world!', @response.body
end
+ # :ported:
def test_render_file_with_instance_variables
get :render_file_with_instance_variables
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_as_string_with_instance_variables
get :render_file_as_string_with_instance_variables
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_not_using_full_path
get :render_file_not_using_full_path
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_not_using_full_path_with_dot_in_path
get :render_file_not_using_full_path_with_dot_in_path
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_using_pathname
get :render_file_using_pathname
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_with_locals
get :render_file_with_locals
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :ported:
def test_render_file_as_string_with_locals
get :render_file_as_string_with_locals
assert_equal "The secret is in the sauce\n", @response.body
end
+ # :assessed:
def test_render_file_from_template
get :render_file_from_template
assert_equal "The secret is in the sauce\n", @response.body
end
- def test_render_json_nil
- get :render_json_nil
- assert_equal 'null', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json
- get :render_json_hello_world
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_with_callback
- get :render_json_hello_world_with_callback
- assert_equal 'alert({"hello":"world"})', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_with_custom_content_type
- get :render_json_with_custom_content_type
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'text/javascript', @response.content_type
- end
-
- def test_render_symbol_json
- get :render_symbol_json
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_with_render_to_string
- get :render_json_with_render_to_string
- assert_equal '{"hello":"partial html"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
# :ported:
def test_render_custom_code
get :render_custom_code
@@ -964,12 +802,6 @@ class RenderTest < ActionController::TestCase
assert_equal 'hello world', @response.body
end
- def test_render_custom_code_rjs
- get :render_custom_code_rjs
- assert_response 404
- assert_equal %(Element.replace("foo", "partial html");), @response.body
- end
-
# :ported:
def test_render_text_with_nil
get :render_text_with_nil
@@ -1023,12 +855,6 @@ class RenderTest < ActionController::TestCase
assert_equal "test", @response.body # name is explicitly set to 'test' inside the controller.
end
- def test_render_vanilla_js
- get :render_vanilla_js_hello
- assert_equal "alert('hello')", @response.body
- assert_equal "text/javascript", @response.content_type
- end
-
# :ported:
def test_render_xml
get :render_xml_hello
@@ -1036,6 +862,7 @@ class RenderTest < ActionController::TestCase
assert_equal "application/xml", @response.content_type
end
+ # :ported:
def test_render_xml_as_string_template
get :render_xml_hello_as_string_template
assert_equal "<html>\n <p>Hello David</p>\n<p>This is grand!</p>\n</html>\n", @response.body
@@ -1048,25 +875,13 @@ class RenderTest < ActionController::TestCase
assert_equal "<p>This is grand!</p>\n", @response.body
end
+ # :move: test in AV
def test_render_xml_with_partial
get :builder_partial_test
assert_equal "<test>\n <hello/>\n</test>\n", @response.body
end
- def test_enum_rjs_test
- ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
- get :enum_rjs_test
- body = %{
- $$(".product").each(function(value, index) {
- new Effect.Highlight(element,{});
- new Effect.Highlight(value,{});
- Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
- new Draggable(value, {});
- });
- }.gsub(/^ /, '').strip
- assert_equal body, @response.body
- end
-
+ # :ported:
def test_layout_rendering
get :layout_test
assert_equal "<html>Hello world!</html>", @response.body
@@ -1114,29 +929,10 @@ class RenderTest < ActionController::TestCase
assert_equal "Goodbye, Local David", @response.body
end
- def test_render_in_an_rjs_template_should_pick_html_templates_when_available
- [:js, "js"].each do |format|
- assert_nothing_raised do
- get :render_implicit_html_template, :format => format
- assert_equal %(document.write("Hello world\\n");), @response.body
- end
- end
- end
-
- def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
- [:js, "js"].each do |format|
- assert_nothing_raised do
- get :render_explicit_html_template, :format => format
- assert_equal %(document.write("Hello world\\n");), @response.body
- end
- end
- end
-
def test_should_implicitly_render_html_template_from_xhr_request
- pending do
- xhr :get, :render_implicit_html_template_from_xhr_request
- assert_equal "XHR!\nHello HTML!", @response.body
- end
+ pending
+ # xhr :get, :render_implicit_html_template_from_xhr_request
+ # assert_equal "XHR!\nHello HTML!", @response.body
end
def test_should_implicitly_render_js_template_without_layout
@@ -1151,11 +947,6 @@ class RenderTest < ActionController::TestCase
assert_equal 'formatted html erb', @response.body
end
- def test_should_render_formatted_xml_erb_template
- get :formatted_xml_erb, :format => :xml
- assert_equal '<test>passed formatted xml erb</test>', @response.body
- end
-
def test_should_render_formatted_html_erb_template
get :formatted_xml_erb
assert_equal '<test>passed formatted html erb</test>', @response.body
@@ -1167,31 +958,6 @@ class RenderTest < ActionController::TestCase
assert_equal '<test>passed formatted html erb</test>', @response.body
end
- def test_should_render_xml_but_keep_custom_content_type
- get :render_xml_with_custom_content_type
- assert_equal "application/atomsvc+xml", @response.content_type
- end
-
- def test_render_with_default_from_accept_header
- xhr :get, :greeting
- assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
- end
-
- def test_render_rjs_with_default
- get :delete_with_js
- assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
- end
-
- def test_render_rjs_template_explicitly
- get :render_js_with_explicit_template
- assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
- end
-
- def test_rendering_rjs_action_explicitly
- get :render_js_with_explicit_action_template
- assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
- end
-
def test_layout_test_with_different_layout
get :layout_test_with_different_layout
assert_equal "<html>Hello world!</html>", @response.body
@@ -1299,28 +1065,6 @@ class RenderTest < ActionController::TestCase
assert_equal "The secret is area51\n", @response.body
end
- def test_update_page
- get :update_page
- assert_template nil
- assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
- assert_equal 2, @response.body.split($/).length
- end
-
- def test_update_page_with_instance_variables
- get :update_page_with_instance_variables
- assert_template nil
- assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
- assert_match /balance/, @response.body
- assert_match /\$37/, @response.body
- end
-
- def test_update_page_with_view_method
- get :update_page_with_view_method
- assert_template nil
- assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
- assert_match /2 people/, @response.body
- end
-
def test_yield_content_for
assert_not_deprecated { get :yield_content_for }
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
@@ -1391,31 +1135,6 @@ class RenderTest < ActionController::TestCase
assert_response :forbidden
end
- def test_rendering_with_location_should_set_header
- get :render_with_location
- assert_equal "http://example.com", @response.headers["Location"]
- end
-
- def test_rendering_xml_should_call_to_xml_if_possible
- get :render_with_to_xml
- assert_equal "<i-am-xml/>", @response.body
- end
-
- def test_rendering_with_object_location_should_set_header_with_url_for
- ActionController::Routing::Routes.draw do |map|
- map.resources :customers
- map.connect ':controller/:action/:id'
- end
-
- get :render_with_object_location
- assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
- end
-
- def test_should_use_implicit_content_type
- get :implicit_content_type, :format => 'atom'
- assert_equal Mime::ATOM, @response.content_type
- end
-
def test_using_layout_around_block
get :render_using_layout_around_block
assert_equal "Before (David)\nInside from block\nAfter", @response.body
@@ -1446,26 +1165,6 @@ class RenderTest < ActionController::TestCase
assert_equal 'partial html', @response.body
end
- def test_should_render_html_formatted_partial_with_rjs
- xhr :get, :partial_as_rjs
- assert_equal %(Element.replace("foo", "partial html");), @response.body
- end
-
- def test_should_render_html_formatted_partial_with_rjs_and_js_format
- xhr :get, :respond_to_partial_as_rjs
- assert_equal %(Element.replace("foo", "partial html");), @response.body
- end
-
- def test_should_render_js_partial
- xhr :get, :partial, :format => 'js'
- assert_equal 'partial js', @response.body
- end
-
- def test_should_render_with_alternate_default_render
- xhr :get, :render_alternate_default
- assert_equal %(Element.replace("foo", "partial html");), @response.body
- end
-
def test_partial_only_with_layout
get :partial_only_with_layout
assert_equal "<html>only partial</html>", @response.body
@@ -1647,7 +1346,7 @@ class EtagRenderTest < ActionController::TestCase
def test_render_against_etag_request_should_304_when_match
@request.if_none_match = etag_for("hello david")
get :render_hello_world_from_variable
- assert_equal 304, @response.status
+ assert_equal 304, @response.status.to_i
assert @response.body.empty?
end
diff --git a/actionpack/test/controller/render_xml_test.rb b/actionpack/test/controller/render_xml_test.rb
new file mode 100644
index 0000000000..052b4f0b52
--- /dev/null
+++ b/actionpack/test/controller/render_xml_test.rb
@@ -0,0 +1,81 @@
+require 'abstract_unit'
+require 'controller/fake_models'
+require 'pathname'
+
+class TestController < ActionController::Base
+ protect_from_forgery
+
+ def render_with_location
+ render :xml => "<hello/>", :location => "http://example.com", :status => 201
+ end
+
+ def render_with_object_location
+ customer = Customer.new("Some guy", 1)
+ render :xml => "<customer/>", :location => customer_url(customer), :status => :created
+ end
+
+ def render_with_to_xml
+ to_xmlable = Class.new do
+ def to_xml
+ "<i-am-xml/>"
+ end
+ end.new
+
+ render :xml => to_xmlable
+ end
+
+ def formatted_xml_erb
+ end
+
+ def render_xml_with_custom_content_type
+ render :xml => "<blah/>", :content_type => "application/atomsvc+xml"
+ end
+end
+
+class RenderTest < ActionController::TestCase
+ tests TestController
+
+ def setup
+ # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
+ # a more accurate simulation of what happens in "real life".
+ super
+ @controller.logger = Logger.new(nil)
+
+ @request.host = "www.nextangle.com"
+ end
+
+ def test_rendering_with_location_should_set_header
+ get :render_with_location
+ assert_equal "http://example.com", @response.headers["Location"]
+ end
+
+ def test_rendering_xml_should_call_to_xml_if_possible
+ get :render_with_to_xml
+ assert_equal "<i-am-xml/>", @response.body
+ end
+
+ def test_rendering_with_object_location_should_set_header_with_url_for
+ ActionController::Routing::Routes.draw do |map|
+ map.resources :customers
+ map.connect ':controller/:action/:id'
+ end
+
+ get :render_with_object_location
+ assert_equal "http://www.nextangle.com/customers/1", @response.headers["Location"]
+ end
+
+ def test_should_render_formatted_xml_erb_template
+ get :formatted_xml_erb, :format => :xml
+ assert_equal '<test>passed formatted xml erb</test>', @response.body
+ end
+
+ def test_should_render_xml_but_keep_custom_content_type
+ get :render_xml_with_custom_content_type
+ assert_equal "application/atomsvc+xml", @response.content_type
+ end
+
+ def test_should_use_implicit_content_type
+ get :implicit_content_type, :format => 'atom'
+ assert_equal Mime::ATOM, @response.content_type
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb
index f745926b20..490a4ff3b3 100644
--- a/actionpack/test/controller/rescue_test.rb
+++ b/actionpack/test/controller/rescue_test.rb
@@ -1,5 +1,19 @@
require 'abstract_unit'
+module ActionDispatch
+ class ShowExceptions
+ private
+ def public_path
+ "#{FIXTURE_LOAD_PATH}/public"
+ end
+
+ # Silence logger
+ def logger
+ nil
+ end
+ end
+end
+
class RescueController < ActionController::Base
class NotAuthorized < StandardError
end
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index f8f562e7c1..0c0c087340 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -6,6 +6,11 @@ module ActionDispatch
def public_path
"#{FIXTURE_LOAD_PATH}/public"
end
+
+ # Silence logger
+ def logger
+ nil
+ end
end
end
diff --git a/actionpack/test/new_base/redirect_test.rb b/actionpack/test/new_base/redirect_test.rb
new file mode 100644
index 0000000000..e591ebd05f
--- /dev/null
+++ b/actionpack/test/new_base/redirect_test.rb
@@ -0,0 +1 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") \ No newline at end of file
diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb
index 348d70381b..626c7b3540 100644
--- a/actionpack/test/new_base/render_action_test.rb
+++ b/actionpack/test/new_base/render_action_test.rb
@@ -92,7 +92,7 @@ module RenderAction
test "raises an exception when requesting a layout and none exist" do
assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do
- get "/render_action/basic/hello_world_with_layout"
+ get "/render_action/basic/hello_world_with_layout", {}, "action_dispatch.show_exceptions" => false
end
end
end
@@ -117,7 +117,9 @@ module RenderAction
describe "rendering a normal template with full path with layout => 'greetings'"
test "raises an exception when requesting a layout that does not exist" do
- assert_raise(ActionView::MissingTemplate) { get "/render_action/basic/hello_world_with_custom_layout" }
+ assert_raise(ActionView::MissingTemplate) do
+ get "/render_action/basic/hello_world_with_custom_layout", {}, "action_dispatch.show_exceptions" => false
+ end
end
end
@@ -131,8 +133,10 @@ module RenderActionWithApplicationLayout
# Set the view path to an application view structure with layouts
self.view_paths = self.view_paths = [ActionView::Template::FixturePath.new(
"render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!",
+ "render_action_with_application_layout/basic/hello.html.builder" => "xml.p 'Omg'",
"layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI",
- "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai"
+ "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai",
+ "layouts/builder.html.builder" => "xml.html do\n xml << yield\nend"
)]
def hello_world
@@ -154,6 +158,10 @@ module RenderActionWithApplicationLayout
def hello_world_with_custom_layout
render :action => "hello_world", :layout => "greetings"
end
+
+ def with_builder_and_layout
+ render :action => "hello", :layout => "builder"
+ end
end
class TestDefaultLayout < SimpleRouteCase
@@ -199,6 +207,15 @@ module RenderActionWithApplicationLayout
assert_status 200
end
+ class TestLayout < SimpleRouteCase
+ testing BasicController
+
+ test "builder works with layouts" do
+ get :with_builder_and_layout
+ assert_response "<html>\n<p>Omg</p>\n</html>\n"
+ end
+ end
+
end
module RenderActionWithControllerLayout
diff --git a/actionpack/test/new_base/render_file_test.rb b/actionpack/test/new_base/render_file_test.rb
new file mode 100644
index 0000000000..769949be0c
--- /dev/null
+++ b/actionpack/test/new_base/render_file_test.rb
@@ -0,0 +1,110 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+
+module RenderFile
+
+ class BasicController < ActionController::Base
+ self.view_paths = "."
+
+ def index
+ 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')
+ end
+
+ def without_file_key
+ 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')
+ end
+
+ def relative_path
+ @secret = 'in the sauce'
+ 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'
+ 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])
+ end
+
+ def with_locals
+ 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')
+ render path, :locals => {:secret => 'in the sauce'}
+ end
+ end
+
+ class TestBasic < SimpleRouteCase
+ 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 \ No newline at end of file
diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb
index 5d28926cc6..dc858b4f5c 100644
--- a/actionpack/test/new_base/render_layout_test.rb
+++ b/actionpack/test/new_base/render_layout_test.rb
@@ -6,7 +6,8 @@ module ControllerLayouts
self.view_paths = [ActionView::Template::FixturePath.new(
"layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI",
"layouts/override.html.erb" => "Override! <%= yield %>",
- "basic.html.erb" => "Hello world!"
+ "basic.html.erb" => "Hello world!",
+ "controller_layouts/implicit/layout_false.html.erb" => "hai(layout_false.html.erb)"
)]
def index
@@ -17,6 +18,10 @@ module ControllerLayouts
render :template => "basic", :layout => "override"
end
+ def layout_false
+ render :layout => false
+ end
+
def builder_override
end
@@ -56,4 +61,13 @@ module ControllerLayouts
get "/controller_layouts/implicit/override"
assert_body "Override! Hello world!"
end
+
+ class TestLayoutOptions < SimpleRouteCase
+ testing ControllerLayouts::ImplicitController
+
+ test "rendering with :layout => false leaves out the implicit layout" do
+ get :layout_false
+ assert_response "hai(layout_false.html.erb)"
+ end
+ end
end \ No newline at end of file
diff --git a/actionpack/test/new_base/render_partial_test.rb b/actionpack/test/new_base/render_partial_test.rb
new file mode 100644
index 0000000000..3a300afe5c
--- /dev/null
+++ b/actionpack/test/new_base/render_partial_test.rb
@@ -0,0 +1,27 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+
+module RenderPartial
+
+ class BasicController < ActionController::Base
+
+ self.view_paths = [ActionView::Template::FixturePath.new(
+ "render_partial/basic/_basic.html.erb" => "OMG!",
+ "render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>"
+ )]
+
+ def changing
+ @test_unchanged = 'hello'
+ render :action => "basic"
+ end
+ end
+
+ class TestPartial < SimpleRouteCase
+ testing BasicController
+
+ test "rendering a partial in ActionView doesn't pull the ivars again from the controller" do
+ get :changing
+ assert_response("goodbyeOMG!goodbye")
+ end
+ end
+
+end \ No newline at end of file
diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb
index c09eeb1926..6c50ae4203 100644
--- a/actionpack/test/new_base/render_template_test.rb
+++ b/actionpack/test/new_base/render_template_test.rb
@@ -4,14 +4,19 @@ module RenderTemplate
class WithoutLayoutController < ActionController::Base
self.view_paths = [ActionView::Template::FixturePath.new(
- "test/basic.html.erb" => "Hello from basic.html.erb",
- "shared.html.erb" => "Elastica",
- "locals.html.erb" => "The secret is <%= secret %>"
+ "test/basic.html.erb" => "Hello from basic.html.erb",
+ "shared.html.erb" => "Elastica",
+ "locals.html.erb" => "The secret is <%= secret %>",
+ "xml_template.xml.builder" => "xml.html do\n xml.p 'Hello'\nend"
)]
def index
render :template => "test/basic"
end
+
+ def index_without_key
+ render "test/basic"
+ end
def in_top_directory
render :template => 'shared'
@@ -21,41 +26,56 @@ module RenderTemplate
render :template => '/shared'
end
+ def in_top_directory_with_slash_without_key
+ render '/shared'
+ end
+
def with_locals
render :template => "locals", :locals => { :secret => 'area51' }
end
+
+ def builder_template
+ render :template => "xml_template"
+ end
end
class TestWithoutLayout < SimpleRouteCase
- describe "rendering a normal template with full path without layout"
+ testing RenderTemplate::WithoutLayoutController
- get "/render_template/without_layout"
- assert_body "Hello from basic.html.erb"
- assert_status 200
- end
-
- class TestTemplateRenderInTopDirectory < SimpleRouteCase
- describe "rendering a template not in a subdirectory"
+ test "rendering a normal template with full path without layout" do
+ get :index
+ assert_response "Hello from basic.html.erb"
+ end
- get "/render_template/without_layout/in_top_directory"
- assert_body "Elastica"
- assert_status 200
- end
-
- class TestTemplateRenderInTopDirectoryWithSlash < SimpleRouteCase
- describe "rendering a template not in a subdirectory with a leading slash"
+ test "rendering a normal template with full path without layout without key" do
+ get :index_without_key
+ assert_response "Hello from basic.html.erb"
+ end
- get "/render_template/without_layout/in_top_directory_with_slash"
- assert_body "Elastica"
- assert_status 200
- end
-
- class TestTemplateRenderWithLocals < SimpleRouteCase
- describe "rendering a template with local variables"
+ test "rendering a template not in a subdirectory" do
+ get :in_top_directory
+ assert_response "Elastica"
+ end
- get "/render_template/without_layout/with_locals"
- assert_body "The secret is area51"
- assert_status 200
+ test "rendering a template not in a subdirectory with a leading slash" do
+ get :in_top_directory_with_slash
+ assert_response "Elastica"
+ end
+
+ test "rendering a template not in a subdirectory with a leading slash without key" do
+ get :in_top_directory_with_slash_without_key
+ assert_response "Elastica"
+ end
+
+ test "rendering a template with local variables" do
+ get :with_locals
+ assert_response "The secret is area51"
+ end
+
+ test "rendering a builder template" do
+ get :builder_template
+ assert_response "<html>\n <p>Hello</p>\n</html>\n"
+ end
end
class WithLayoutController < ::ApplicationController
diff --git a/actionpack/test/new_base/render_test.rb b/actionpack/test/new_base/render_test.rb
index b1867fdcc2..ef5e7d89c5 100644
--- a/actionpack/test/new_base/render_test.rb
+++ b/actionpack/test/new_base/render_test.rb
@@ -48,7 +48,7 @@ module Render
test "raises an exception" do
assert_raises(AbstractController::DoubleRenderError) do
- get "/render/double_render"
+ get "/render/double_render", {}, "action_dispatch.show_exceptions" => false
end
end
end
@@ -58,13 +58,13 @@ module Render
test "raises an exception when a method of Object is called" do
assert_raises(AbstractController::ActionNotFound) do
- get "/render/blank_render/clone"
+ get "/render/blank_render/clone", {}, "action_dispatch.show_exceptions" => false
end
end
test "raises an exception when a private method is called" do
assert_raises(AbstractController::ActionNotFound) do
- get "/render/blank_render/secretz"
+ get "/render/blank_render/secretz", {}, "action_dispatch.show_exceptions" => false
end
end
end
diff --git a/actionpack/test/new_base/render_xml_test.rb b/actionpack/test/new_base/render_xml_test.rb
new file mode 100644
index 0000000000..e6c40b1533
--- /dev/null
+++ b/actionpack/test/new_base/render_xml_test.rb
@@ -0,0 +1,11 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+
+module RenderXml
+
+ # This has no layout and it works
+ class BasicController < ActionController::Base
+ self.view_paths = [ActionView::Template::FixturePath.new(
+ "render_xml/basic/with_render_erb" => "Hello world!"
+ )]
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb
index 78662dc989..ec7dbffaae 100644
--- a/actionpack/test/new_base/test_helper.rb
+++ b/actionpack/test/new_base/test_helper.rb
@@ -46,7 +46,7 @@ class Rack::TestCase < ActiveSupport::TestCase
ActionController::Routing.use_controllers!(controllers)
# Move into a bootloader
- AbstractController::Base.subclasses.each do |klass|
+ ActionController::Base.subclasses.each do |klass|
klass = klass.constantize
next unless klass < AbstractController::Layouts
klass.class_eval do
@@ -59,12 +59,28 @@ class Rack::TestCase < ActiveSupport::TestCase
@app ||= ActionController::Dispatcher.new
end
+ def self.testing(klass = nil)
+ if klass
+ @testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
+ else
+ @testing
+ end
+ end
+
def self.get(url)
setup do |test|
test.get url
end
end
+ def get(thing, *args)
+ if thing.is_a?(Symbol)
+ super("#{self.class.testing}/#{thing}")
+ else
+ super
+ end
+ end
+
def assert_body(body)
assert_equal body, Array.wrap(last_response.body).join
end
@@ -85,6 +101,14 @@ class Rack::TestCase < ActiveSupport::TestCase
end
end
+ def assert_response(body, status = 200, headers = {})
+ assert_body body
+ assert_status status
+ headers.each do |header, value|
+ assert_header header, value
+ end
+ end
+
def assert_content_type(type)
assert_equal type, last_response.headers["Content-Type"]
end
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 78db87971b..73624406be 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -80,6 +80,14 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_string_options_for_select
+ options = "<option value=\"Denmark\">Denmark</option><option value=\"USA\">USA</option><option value=\"Sweden\">Sweden</option>"
+ assert_dom_equal(
+ options,
+ options_for_select(options)
+ )
+ end
+
def test_array_options_for_select
assert_dom_equal(
"<option value=\"&lt;Denmark&gt;\">&lt;Denmark&gt;</option>\n<option value=\"USA\">USA</option>\n<option value=\"Sweden\">Sweden</option>",
@@ -324,6 +332,20 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_under_fields_for_with_string_and_given_prompt
+ @post = Post.new
+ options = "<option value=\"abe\">abe</option><option value=\"mus\">mus</option><option value=\"hest\">hest</option>"
+
+ fields_for :post, @post do |f|
+ concat f.select(:category, options, :prompt => 'The prompt')
+ end
+
+ assert_dom_equal(
+ "<select id=\"post_category\" name=\"post[category]\"><option value=\"\">The prompt</option>\n#{options}</select>",
+ output_buffer
+ )
+ end
+
def test_select_with_blank
@post = Post.new
@post.category = "<mus>"
diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb
index 29cb60fd73..b6542ef29d 100644
--- a/actionpack/test/template/number_helper_test.rb
+++ b/actionpack/test/template/number_helper_test.rb
@@ -118,6 +118,10 @@ class NumberHelperTest < ActionView::TestCase
assert_equal '1.01 KB', number_to_human_size(1.0123.kilobytes, :precision => 2)
assert_equal '1.01 KB', number_to_human_size(1.0100.kilobytes, :precision => 4)
assert_equal '10 KB', number_to_human_size(10.000.kilobytes, :precision => 4)
+ assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 0)
+ assert_equal '500 MB', number_to_human_size(524288000, :precision=>0)
+ assert_equal '40 KB', number_to_human_size(41010, :precision => 0)
+ assert_equal '40 KB', number_to_human_size(41100, :precision => 0)
end
def test_number_to_human_size_with_custom_delimiter_and_separator
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index be7163888e..a780bfc606 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -401,6 +401,13 @@ class TextHelperTest < ActionView::TestCase
auto_link("Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com.",
:link => :all, :html => { :class => "menu", :target => "_blank" })
end
+
+ def test_auto_link_with_multiple_trailing_punctuations
+ url = "http://youtube.com"
+ url_result = generate_result(url)
+ assert_equal url_result, auto_link(url)
+ assert_equal "(link: #{url_result}).", auto_link("(link: #{url}).")
+ end
def test_cycle_class
value = Cycle.new("one", 2, "3")
diff --git a/activemodel/Rakefile b/activemodel/Rakefile
index 4b60f8d682..544f49310a 100755
--- a/activemodel/Rakefile
+++ b/activemodel/Rakefile
@@ -11,6 +11,12 @@ Rake::TestTask.new do |t|
t.verbose = true
t.warning = true
end
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir.glob("test/**/*_test.rb").all? do |file|
+ system(ruby, '-Ilib:test', file)
+ end or raise "Failures"
+end
# Generate the RDoc documentation
Rake::RDocTask.new do |rdoc|
diff --git a/activemodel/test/state_machine/event_test.rb b/activemodel/test/state_machine/event_test.rb
index 64dc8c4875..05e7c78e8a 100644
--- a/activemodel/test/state_machine/event_test.rb
+++ b/activemodel/test/state_machine/event_test.rb
@@ -1,4 +1,5 @@
require 'test_helper'
+require 'active_model/state_machine/event'
class EventTest < ActiveModel::TestCase
def setup
diff --git a/activemodel/test/state_machine/state_transition_test.rb b/activemodel/test/state_machine/state_transition_test.rb
index b59ff5a6a7..966396fab1 100644
--- a/activemodel/test/state_machine/state_transition_test.rb
+++ b/activemodel/test/state_machine/state_transition_test.rb
@@ -1,4 +1,5 @@
require 'test_helper'
+require 'active_model/state_machine/state_transition'
class StateTransitionTest < ActiveModel::TestCase
test 'should set from, to, and opts attr readers' do
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index d58b44144b..411b640c9e 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*Edge*
+* Implement #many? for NamedScope and AssociationCollection using #size. #1500 [Chris Kampmeier]
+
* Added :touch option to belongs_to associations that will touch the parent record when the current record is saved or destroyed [DHH]
* Added ActiveRecord::Base#touch to update the updated_at/on attributes (or another specified timestamp) with the current time [DHH]
diff --git a/activerecord/Rakefile b/activerecord/Rakefile
index 5905c67e29..0b3f50d17e 100644
--- a/activerecord/Rakefile
+++ b/activerecord/Rakefile
@@ -32,21 +32,32 @@ desc 'Run mysql, sqlite, and postgresql tests'
task :test => defined?(JRUBY_VERSION) ?
%w(test_jdbcmysql test_jdbcsqlite3 test_jdbcpostgresql) :
%w(test_mysql test_sqlite3 test_postgresql)
+task :isolated_test => defined?(JRUBY_VERSION) ?
+ %w(isolated_test_jdbcmysql isolated_test_jdbcsqlite3 isolated_test_jdbcpostgresql) :
+ %w(isolated_test_mysql isolated_test_sqlite3 isolated_test_postgresql)
-for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb )
+%w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
Rake::TestTask.new("test_#{adapter}") { |t|
- if adapter =~ /jdbc/
- t.libs << "test" << "test/connections/jdbc_#{adapter}"
- else
- t.libs << "test" << "test/connections/native_#{adapter}"
- end
+ connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
+ t.libs << "test" << connection_path
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
t.verbose = true
}
+ task "isolated_test_#{adapter}" do
+ connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
+ adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
+ puts [adapter, adapter_short, connection_path].inspect
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ Dir["test/cases/**/*_test{,_#{adapter_short}}.rb"].all? do |file|
+ system(ruby, "-Ilib:test:#{connection_path}", file)
+ end or raise "Failures"
+ end
+
namespace adapter do
task :test => "test_#{adapter}"
+ task :isolated_test => "isolated_test_#{adapter}"
end
end
diff --git a/activerecord/examples/simple.rb b/activerecord/examples/simple.rb
new file mode 100644
index 0000000000..c12f746992
--- /dev/null
+++ b/activerecord/examples/simple.rb
@@ -0,0 +1,14 @@
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
+require 'active_record'
+
+class Person < ActiveRecord::Base
+ establish_connection :adapter => 'sqlite3', :database => 'foobar.db'
+ connection.create_table table_name, :force => true do |t|
+ t.string :name
+ end
+end
+
+bob = Person.create!(:name => 'bob')
+puts Person.all.inspect
+bob.destroy
+puts Person.all.inspect
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index cf0557101f..9448481884 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -24,7 +24,9 @@
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
$:.unshift(activesupport_path) if File.directory?(activesupport_path)
require 'active_support'
-require 'active_support/core/all'
+
+# TODO: Figure out what parts of AS are *actually* required and use those
+require 'active_support/core_ext'
$:.unshift(File.dirname(__FILE__) + '/../../arel/lib')
require 'arel'
@@ -78,5 +80,4 @@ module ActiveRecord
end
end
-require 'active_record/i18n_interpolation_deprecation'
I18n.load_path << File.dirname(__FILE__) + '/active_record/locale/en.yml'
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 2fe08b2456..2c998faf37 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/module/delegation'
+
module ActiveRecord
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
def initialize(reflection)
@@ -1674,7 +1676,7 @@ module ActiveRecord
def tables_in_string(string)
return [] if string.blank?
- string.scan(/([\.a-zA-Z_]+).?\./).flatten
+ string.scan(/([a-zA-Z_][\.\w]+).?\./).flatten
end
def tables_in_hash(hash)
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb
index 26987dde97..e12f6be35d 100644
--- a/activerecord/lib/active_record/associations/association_collection.rb
+++ b/activerecord/lib/active_record/associations/association_collection.rb
@@ -302,6 +302,15 @@ module ActiveRecord
end
end
+ # Returns true if the collection has more than 1 record. Equivalent to collection.size > 1.
+ def many?
+ if block_given?
+ method_missing(:many?) { |*block_args| yield(*block_args) }
+ else
+ size > 1
+ end
+ end
+
def uniq(collection = self)
seen = Set.new
collection.inject([]) do |kept, record|
diff --git a/activerecord/lib/active_record/associations/has_one_through_association.rb b/activerecord/lib/active_record/associations/has_one_through_association.rb
index 8073ebaf9f..d93c8e7852 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -1,31 +1,31 @@
module ActiveRecord
module Associations
class HasOneThroughAssociation < HasManyThroughAssociation
-
+
def create_through_record(new_value) #nodoc:
klass = @reflection.through_reflection.klass
current_object = @owner.send(@reflection.through_reflection.name)
-
+
if current_object
- current_object.update_attributes(construct_join_attributes(new_value))
+ new_value ? current_object.update_attributes(construct_join_attributes(new_value)) : current_object.destroy
else
- @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value)))
+ @owner.send(@reflection.through_reflection.name, klass.send(:create, construct_join_attributes(new_value))) if new_value
end
end
-
+
private
def find(*args)
super(args.merge(:limit => 1))
end
-
+
def find_target
super.first
end
def reset_target!
@target = nil
- end
- end
+ end
+ end
end
end
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 8d68d77eac..d5e215af9d 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/enumerable'
+
module ActiveRecord
module AttributeMethods #:nodoc:
extend ActiveSupport::DependencyModule
@@ -103,8 +105,8 @@ module ActiveRecord
def instance_method_already_implemented?(method_name)
method_name = method_name.to_s
return true if method_name =~ /^id(=$|\?$|$)/
- @_defined_class_methods ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.map(&:to_s).to_set
- @@_defined_activerecord_methods ||= (ActiveRecord::Base.public_instance_methods(false) | ActiveRecord::Base.private_instance_methods(false) | ActiveRecord::Base.protected_instance_methods(false)).map(&:to_s).to_set
+ @_defined_class_methods ||= ancestors.first(ancestors.index(ActiveRecord::Base)).sum([]) { |m| m.public_instance_methods(false) | m.private_instance_methods(false) | m.protected_instance_methods(false) }.map {|m| m.to_s }.to_set
+ @@_defined_activerecord_methods ||= (ActiveRecord::Base.public_instance_methods(false) | ActiveRecord::Base.private_instance_methods(false) | ActiveRecord::Base.protected_instance_methods(false)).map{|m| m.to_s }.to_set
raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord" if @@_defined_activerecord_methods.include?(method_name)
@_defined_class_methods.include?(method_name)
end
@@ -122,7 +124,7 @@ module ActiveRecord
# with datatype <tt>:datetime, :timestamp, :time, :date</tt> are cached.
def cached_attributes
@cached_attributes ||=
- columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map(&:name).to_set
+ columns.select{|c| attribute_types_cached_by_default.include?(c.type)}.map{|col| col.name}.to_set
end
# Returns +true+ if the provided attribute is being cached.
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index bdfb0f45aa..3b12b15a5f 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1,6 +1,15 @@
require 'yaml'
require 'set'
require 'active_support/dependencies'
+require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/class/delegating_attributes'
+require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/hash/deep_merge'
+require 'active_support/core_ext/hash/indifferent_access'
+require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/string/behavior'
+require 'active_support/core/time'
module ActiveRecord #:nodoc:
# Generic Active Record exception class.
@@ -688,9 +697,9 @@ module ActiveRecord #:nodoc:
# Person.exists?(['name LIKE ?', "%#{query}%"])
# Person.exists?
def exists?(id_or_conditions = {})
- connection.select_all(construct_finder_arel({
- :conditions => expand_id_conditions(id_or_conditions)
- }).project(arel_table[primary_key]).take(1).to_sql).size > 0
+ find_initial(
+ :select => "#{quoted_table_name}.#{primary_key}",
+ :conditions => expand_id_conditions(id_or_conditions)) ? true : false
end
# Creates an object (or multiple objects) and saves it to the database, if validations pass.
@@ -1024,7 +1033,7 @@ module ActiveRecord #:nodoc:
# To start from an all-closed default and enable attributes as needed,
# have a look at +attr_accessible+.
def attr_protected(*attributes)
- write_inheritable_attribute(:attr_protected, Set.new(attributes.map(&:to_s)) + (protected_attributes || []))
+ write_inheritable_attribute(:attr_protected, Set.new(attributes.map {|a| a.to_s}) + (protected_attributes || []))
end
# Returns an array of all the attributes that have been protected from mass-assignment.
@@ -1951,7 +1960,7 @@ module ActiveRecord #:nodoc:
else
find(:#{finder}, options.merge(finder_options))
end
- #{'result || raise(RecordNotFound, "Couldn\'t find #{name} with #{attributes.to_a.collect {|pair| "#{pair.first} = #{pair.second}"}.join(\', \')}")' if bang}
+ #{'result || raise(RecordNotFound, "Couldn\'t find #{name} with #{attributes.to_a.collect { |pair| pair.join(\' = \') }.join(\', \')}")' if bang}
end
}, __FILE__, __LINE__
send(method_id, *arguments)
@@ -2669,11 +2678,11 @@ module ActiveRecord #:nodoc:
# Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either
# instance will affect the other.
def becomes(klass)
- returning klass.new do |became|
- became.instance_variable_set("@attributes", @attributes)
- became.instance_variable_set("@attributes_cache", @attributes_cache)
- became.instance_variable_set("@new_record", new_record?)
- end
+ became = klass.new
+ became.instance_variable_set("@attributes", @attributes)
+ became.instance_variable_set("@attributes_cache", @attributes_cache)
+ became.instance_variable_set("@new_record", new_record?)
+ became
end
# Updates a single attribute and saves the record without going through the normal validation procedure.
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index e8e736bf38..500dafdc2e 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -1,5 +1,6 @@
require 'monitor'
require 'set'
+require 'active_support/core_ext/module/synchronization'
module ActiveRecord
# Raised when a connection could not be obtained within the connection
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
index 3a7bf35248..720fba29e9 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/big_decimal/conversions'
+
module ActiveRecord
module ConnectionAdapters # :nodoc:
module Quoting
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index a8cd9f033b..91b111ab55 100755
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -12,6 +12,8 @@ require 'active_record/connection_adapters/abstract/connection_pool'
require 'active_record/connection_adapters/abstract/connection_specification'
require 'active_record/connection_adapters/abstract/query_cache'
+require 'active_support/core_ext/benchmark'
+
module ActiveRecord
module ConnectionAdapters # :nodoc:
# ActiveRecord supports multiple database systems. AbstractAdapter and
diff --git a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
index 8d8df7dece..0aae97a6a9 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb
@@ -1,4 +1,5 @@
require 'active_record/connection_adapters/abstract_adapter'
+require 'active_support/core_ext/kernel/requires'
require 'set'
module MysqlCompat #:nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 12b2c4a4d1..4b2ddac634 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -1,4 +1,5 @@
require 'active_record/connection_adapters/abstract_adapter'
+require 'active_support/core_ext/kernel/requires'
begin
require_library_or_gem 'pg'
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 75420f69aa..5eef692d05 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -25,9 +25,9 @@ module ActiveRecord
module ConnectionAdapters #:nodoc:
class SQLite3Adapter < SQLiteAdapter # :nodoc:
def table_structure(table_name)
- returning structure = @connection.table_info(quote_table_name(table_name)) do
- raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
- end
+ structure = @connection.table_info(quote_table_name(table_name))
+ raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
+ structure
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 05334a830a..c9d0c9574f 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -1,4 +1,5 @@
require 'active_record/connection_adapters/abstract_adapter'
+require 'active_support/core_ext/kernel/requires'
module ActiveRecord
class Base
diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb
index fac6ca40d3..ac84f6b209 100644
--- a/activerecord/lib/active_record/dirty.rb
+++ b/activerecord/lib/active_record/dirty.rb
@@ -168,7 +168,9 @@ module ActiveRecord
module ClassMethods
def self.extended(base)
- base.metaclass.alias_method_chain(:alias_attribute, :dirty)
+ class << base
+ alias_method_chain :alias_attribute, :dirty
+ end
end
def alias_attribute_with_dirty(new_name, old_name)
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index 91b4b4e182..e30fcf9a4f 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -3,6 +3,7 @@ require 'yaml'
require 'csv'
require 'active_support/dependencies'
require 'active_support/test_case'
+require 'active_support/core_ext/logger'
if RUBY_VERSION < '1.9'
module YAML #:nodoc:
diff --git a/activerecord/lib/active_record/i18n_interpolation_deprecation.rb b/activerecord/lib/active_record/i18n_interpolation_deprecation.rb
deleted file mode 100644
index cd634e1b8d..0000000000
--- a/activerecord/lib/active_record/i18n_interpolation_deprecation.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# Deprecates the use of the former message interpolation syntax in activerecord
-# as in "must have %d characters". The new syntax uses explicit variable names
-# as in "{{value}} must have {{count}} characters".
-
-require 'i18n/backend/simple'
-module I18n
- module Backend
- class Simple
- DEPRECATED_INTERPOLATORS = { '%d' => '{{count}}', '%s' => '{{value}}' }
-
- protected
- def interpolate_with_deprecated_syntax(locale, string, values = {})
- return string unless string.is_a?(String)
-
- string = string.gsub(/%d|%s/) do |s|
- instead = DEPRECATED_INTERPOLATORS[s]
- ActiveSupport::Deprecation.warn "using #{s} in messages is deprecated; use #{instead} instead."
- instead
- end
-
- interpolate_without_deprecated_syntax(locale, string, values)
- end
- alias_method_chain :interpolate, :deprecated_syntax
- end
- end
-end \ No newline at end of file
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index ce02fe019f..557ab07abf 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -508,11 +508,11 @@ module ActiveRecord
raise DuplicateMigrationNameError.new(name.camelize)
end
- klasses << returning(MigrationProxy.new) do |migration|
- migration.name = name.camelize
- migration.version = version
- migration.filename = file
- end
+ migration = MigrationProxy.new
+ migration.name = name.camelize
+ migration.version = version
+ migration.filename = file
+ klasses << migration
end
migrations = migrations.sort_by(&:version)
diff --git a/activerecord/lib/active_record/named_scope.rb b/activerecord/lib/active_record/named_scope.rb
index 32bb36c07c..e7151a3d47 100644
--- a/activerecord/lib/active_record/named_scope.rb
+++ b/activerecord/lib/active_record/named_scope.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/array'
+require 'active_support/core_ext/hash/except'
+
module ActiveRecord
module NamedScope
extend ActiveSupport::DependencyModule
@@ -106,7 +109,7 @@ module ActiveRecord
class Scope
attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
- NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set
+ NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? many? respond_to?).to_set
[].methods.each do |m|
unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
delegate m, :to => :proxy_found
@@ -165,6 +168,15 @@ module ActiveRecord
end
end
+ # Returns true if the named scope has more than 1 matching record.
+ def many?
+ if block_given?
+ proxy_found.many? { |*block_args| yield(*block_args) }
+ else
+ size > 1
+ end
+ end
+
protected
def proxy_found
@found || load_found
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 1ea2f53fd8..c532d3dfa3 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/object/try'
+
module ActiveRecord
module NestedAttributes #:nodoc:
extend ActiveSupport::DependencyModule
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 557a554966..de530a3456 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -1,5 +1,5 @@
require 'stringio'
-require 'bigdecimal'
+require 'active_support/core_ext/big_decimal'
module ActiveRecord
# This class is used to dump the database schema for some connection to some
@@ -176,4 +176,4 @@ HEADER
end
end
end
-end \ No newline at end of file
+end
diff --git a/activerecord/lib/active_record/serialization.rb b/activerecord/lib/active_record/serialization.rb
index 78f66c3a73..7959f2b510 100644
--- a/activerecord/lib/active_record/serialization.rb
+++ b/activerecord/lib/active_record/serialization.rb
@@ -1,5 +1,3 @@
-require 'active_support/json'
-
module ActiveRecord #:nodoc:
module Serialization
class Serializer #:nodoc:
@@ -73,16 +71,19 @@ module ActiveRecord #:nodoc:
end
def serializable_record
- returning(serializable_record = {}) do
- serializable_names.each { |name| serializable_record[name] = @record.send(name) }
- add_includes do |association, records, opts|
+ record = {}
+ serializable_names.each { |name| record[name] = @record.send(name) }
+
+ add_includes do |association, records, opts|
+ record[association] =
if records.is_a?(Enumerable)
- serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record }
+ records.collect { |r| self.class.new(r, opts).serializable_record }
else
- serializable_record[association] = self.class.new(records, opts).serializable_record
+ self.class.new(records, opts).serializable_record
end
- end
end
+
+ record
end
def serialize
diff --git a/activerecord/lib/active_record/serializers/xml_serializer.rb b/activerecord/lib/active_record/serializers/xml_serializer.rb
index fa75874603..4eaf9531e2 100644
--- a/activerecord/lib/active_record/serializers/xml_serializer.rb
+++ b/activerecord/lib/active_record/serializers/xml_serializer.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/hash/conversions'
+
module ActiveRecord #:nodoc:
module Serialization
# Builds an XML document to represent the model. Some configuration is
@@ -165,8 +167,9 @@ module ActiveRecord #:nodoc:
class XmlSerializer < ActiveRecord::Serialization::Serializer #:nodoc:
def builder
@builder ||= begin
+ require 'builder' unless defined? ::Builder
options[:indent] ||= 2
- builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
+ builder = options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
unless options[:skip_instruct]
builder.instruct!
diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb
index 21471da419..9dda3361d8 100644
--- a/activerecord/lib/active_record/session_store.rb
+++ b/activerecord/lib/active_record/session_store.rb
@@ -295,7 +295,7 @@ module ActiveRecord
def set_session(env, sid, session_data)
Base.silence do
- record = env[SESSION_RECORD_KEY] ||= find_session(sid)
+ record = get_session_model(env, sid)
record.data = session_data
return false unless record.save
@@ -309,6 +309,14 @@ module ActiveRecord
return true
end
+
+ def get_session_model(env, sid)
+ if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
+ env[SESSION_RECORD_KEY] = find_session(sid)
+ else
+ env[SESSION_RECORD_KEY] ||= find_session(sid)
+ end
+ end
def find_session(id)
@@session_class.find_by_session_id(id) ||
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index 9907a3c9b7..b6e848fa79 100644
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -1,5 +1,3 @@
-require 'builder'
-
module ActiveRecord
# Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
# +record+ method to retrieve the record which did not validate.
@@ -247,9 +245,10 @@ module ActiveRecord
# # <error>Address can't be blank</error>
# # </errors>
def to_xml(options={})
+ require 'builder' unless defined? ::Builder
options[:root] ||= "errors"
options[:indent] ||= 2
- options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
+ options[:builder] ||= ::Builder::XmlMarkup.new(:indent => options[:indent])
options[:builder].instruct! unless options.delete(:skip_instruct)
options[:builder].errors do |e|
diff --git a/activerecord/test/cases/aaa_create_tables_test.rb b/activerecord/test/cases/aaa_create_tables_test.rb
deleted file mode 100644
index 3911afac49..0000000000
--- a/activerecord/test/cases/aaa_create_tables_test.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# The filename begins with "aaa" to ensure this is the first test.
-require "cases/helper"
-
-class AAACreateTablesTest < ActiveRecord::TestCase
- self.use_transactional_fixtures = false
-
- def test_load_schema
- eval(File.read(SCHEMA_ROOT + "/schema.rb"))
- if File.exists?(adapter_specific_schema_file)
- eval(File.read(adapter_specific_schema_file))
- end
- assert true
- end
-
- def test_drop_and_create_courses_table
- eval(File.read(SCHEMA_ROOT + "/schema2.rb"))
- assert true
- end
-
- private
- def adapter_specific_schema_file
- SCHEMA_ROOT + '/' + ActiveRecord::Base.connection.adapter_name.downcase + '_specific_schema.rb'
- end
-end
diff --git a/activerecord/test/cases/aggregations_test.rb b/activerecord/test/cases/aggregations_test.rb
index 4e0e1c7f15..8b6ec04018 100644
--- a/activerecord/test/cases/aggregations_test.rb
+++ b/activerecord/test/cases/aggregations_test.rb
@@ -1,5 +1,6 @@
require "cases/helper"
require 'models/customer'
+require 'active_support/core_ext/exception'
class AggregationsTest < ActiveRecord::TestCase
fixtures :customers
diff --git a/activerecord/test/cases/associations/eager_load_nested_include_test.rb b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
index 5f824f9c74..cb7fe9698b 100644
--- a/activerecord/test/cases/associations/eager_load_nested_include_test.rb
+++ b/activerecord/test/cases/associations/eager_load_nested_include_test.rb
@@ -4,6 +4,7 @@ require 'models/author'
require 'models/comment'
require 'models/category'
require 'models/categorization'
+require 'active_support/core_ext/array/random_access'
module Remembered
extend ActiveSupport::DependencyModule
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index d23f86b700..65049c4f87 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -589,6 +589,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal posts(:sti_post_and_comments, :sti_comments), Post.find(:all, :include => [:author, :comments], :conditions => "authors.name = 'David'", :order => 'UPPER(posts.title) DESC, posts.id', :limit => 2, :offset => 1)
end
+ def test_limited_eager_with_numeric_in_association
+ assert_equal people(:david, :susan), Person.find(:all, :include => [:readers, :primary_contact, :number1_fan], :conditions => "number1_fans_people.first_name like 'M%'", :order => 'readers.id', :limit => 2, :offset => 0)
+ end
+
def test_preload_with_interpolation
assert_equal [comments(:greetings)], Post.find(posts(:welcome).id, :include => :comments_with_interpolated_conditions).comments_with_interpolated_conditions
end
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index 5e8b2cadfc..8dc95806b9 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -24,6 +24,7 @@ require 'models/club'
require 'models/member'
require 'models/membership'
require 'models/sponsor'
+require 'active_support/core_ext/string/conversions'
class ProjectWithAfterCreateHook < ActiveRecord::Base
set_table_name 'projects'
diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb
index 5df74fcdcd..d99424f9cd 100644
--- a/activerecord/test/cases/associations/has_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb
@@ -1023,6 +1023,45 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert firm.clients.loaded?
end
+ def test_calling_many_should_count_instead_of_loading_association
+ firm = companies(:first_firm)
+ assert_queries(1) do
+ firm.clients.many? # use count query
+ end
+ assert !firm.clients.loaded?
+ end
+
+ def test_calling_many_on_loaded_association_should_not_use_query
+ firm = companies(:first_firm)
+ firm.clients.collect # force load
+ assert_no_queries { assert firm.clients.many? }
+ end
+
+ def test_calling_many_should_defer_to_collection_if_using_a_block
+ firm = companies(:first_firm)
+ assert_queries(1) do
+ firm.clients.expects(:size).never
+ firm.clients.many? { true }
+ end
+ assert firm.clients.loaded?
+ end
+
+ def test_calling_many_should_return_false_if_none_or_one
+ firm = companies(:another_firm)
+ assert !firm.clients_like_ms.many?
+ assert_equal 0, firm.clients_like_ms.size
+
+ firm = companies(:first_firm)
+ assert !firm.limited_clients.many?
+ assert_equal 1, firm.limited_clients.size
+ end
+
+ def test_calling_many_should_return_true_if_more_than_one
+ firm = companies(:first_firm)
+ assert firm.clients.many?
+ assert_equal 2, firm.clients.size
+ end
+
def test_joins_with_namespaced_model_should_use_correct_type
old = ActiveRecord::Base.store_full_sti_class
ActiveRecord::Base.store_full_sti_class = true
diff --git a/activerecord/test/cases/associations/has_one_through_associations_test.rb b/activerecord/test/cases/associations/has_one_through_associations_test.rb
index 12c598751b..ab6e6d20fc 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -43,7 +43,14 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
@member.reload
end
end
-
+
+ def test_set_record_to_nil_should_delete_association
+ @member.club = nil
+ @member.reload
+ assert_equal nil, @member.current_membership
+ assert_nil @member.club
+ end
+
def test_has_one_through_polymorphic
assert_equal clubs(:moustache_club), @member.sponsor_club
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 7ca2807f7e..59aa6953e3 100755
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -18,6 +18,7 @@ require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
require 'rexml/document'
+require 'active_support/core_ext/exception'
class Category < ActiveRecord::Base; end
class Categorization < ActiveRecord::Base; end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 28eb311618..d0d7094e30 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -119,6 +119,12 @@ class FinderTest < ActiveRecord::TestCase
Address.new(existing_address.street + "1", existing_address.city, existing_address.country))
end
+ def test_exists_with_scoped_include
+ Developer.with_scope(:find => { :include => :projects, :order => "projects.name" }) do
+ assert Developer.exists?
+ end
+ end
+
def test_find_by_array_of_one_id
assert_kind_of(Array, Topic.find([ 1 ]))
assert_equal(1, Topic.find([ 1 ]).length)
@@ -485,8 +491,9 @@ class FinderTest < ActiveRecord::TestCase
assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', [])
end
- def test_bind_string
- assert_equal ActiveRecord::Base.connection.quote(''), bind('?', '')
+ def test_bind_empty_string
+ quoted_empty = ActiveRecord::Base.connection.quote('')
+ assert_equal quoted_empty, bind('?', '')
end
def test_bind_chars
diff --git a/activerecord/test/cases/helper.rb b/activerecord/test/cases/helper.rb
index 2b623ea703..f82784836e 100644
--- a/activerecord/test/cases/helper.rb
+++ b/activerecord/test/cases/helper.rb
@@ -5,6 +5,7 @@ require 'config'
require 'rubygems'
require 'test/unit'
+require 'stringio'
gem 'mocha', '>= 0.9.5'
require 'mocha'
@@ -15,7 +16,6 @@ require 'connection'
require 'cases/repair_helper'
-# Expose the debugger if available
begin
require 'ruby-debug'
rescue LoadError
@@ -73,3 +73,20 @@ class ActiveSupport::TestCase
Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block)
end
end
+
+# silence verbose schema loading
+original_stdout = $stdout
+$stdout = StringIO.new
+
+begin
+ adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
+ adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
+
+ load SCHEMA_ROOT + "/schema.rb"
+
+ if File.exists?(adapter_specific_schema_file)
+ load adapter_specific_schema_file
+ end
+ensure
+ $stdout = original_stdout
+end
diff --git a/activerecord/test/cases/named_scope_test.rb b/activerecord/test/cases/named_scope_test.rb
index 4929f09812..cff648795f 100644
--- a/activerecord/test/cases/named_scope_test.rb
+++ b/activerecord/test/cases/named_scope_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+require 'active_support/core_ext/array/random_access'
require 'models/post'
require 'models/topic'
require 'models/comment'
@@ -234,6 +235,40 @@ class NamedScopeTest < ActiveRecord::TestCase
assert_no_queries { assert topics.any? }
end
+ def test_many_should_not_load_results
+ topics = Topic.base
+ assert_queries(2) do
+ topics.many? # use count query
+ topics.collect # force load
+ topics.many? # use loaded (no query)
+ end
+ end
+
+ def test_many_should_call_proxy_found_if_using_a_block
+ topics = Topic.base
+ assert_queries(1) do
+ topics.expects(:size).never
+ topics.many? { true }
+ end
+ end
+
+ def test_many_should_not_fire_query_if_named_scope_loaded
+ topics = Topic.base
+ topics.collect # force load
+ assert_no_queries { assert topics.many? }
+ end
+
+ def test_many_should_return_false_if_none_or_one
+ topics = Topic.base.scoped(:conditions => {:id => 0})
+ assert !topics.many?
+ topics = Topic.base.scoped(:conditions => {:id => 1})
+ assert !topics.many?
+ end
+
+ def test_many_should_return_true_if_more_than_one
+ assert Topic.base.many?
+ end
+
def test_should_build_with_proxy_options
topic = Topic.approved.build({})
assert topic.approved
@@ -265,7 +300,7 @@ class NamedScopeTest < ActiveRecord::TestCase
end
def test_rand_should_select_a_random_object_from_proxy
- assert Topic.approved.rand.is_a?(Topic)
+ assert_kind_of Topic, Topic.approved.rand
end
def test_should_use_where_in_query_for_named_scope
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index f1741ed54d..f31275163d 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -4,6 +4,7 @@ require "models/ship"
require "models/bird"
require "models/parrot"
require "models/treasure"
+require 'active_support/hash_with_indifferent_access'
module AssertRaiseWithMessage
def assert_raise_with_message(expected_exception, expected_message)
diff --git a/activerecord/test/cases/validations_i18n_test.rb b/activerecord/test/cases/validations_i18n_test.rb
index 66982346e9..20d1369a64 100644
--- a/activerecord/test/cases/validations_i18n_test.rb
+++ b/activerecord/test/cases/validations_i18n_test.rb
@@ -38,35 +38,17 @@ class ActiveRecordValidationsI18nTests < ActiveSupport::TestCase
end
end
- def test_default_error_messages_is_deprecated
- assert_deprecated('ActiveRecord::Errors.default_error_messages') do
- ActiveRecord::Errors.default_error_messages
+ def test_percent_s_interpolation_syntax_in_error_messages_was_deprecated
+ assert_not_deprecated do
+ default = "%s interpolation syntax was deprecated"
+ assert_equal default, I18n.t(:does_not_exist, :default => default, :value => 'this')
end
end
- def test_percent_s_interpolation_syntax_in_error_messages_still_works
- ActiveSupport::Deprecation.silence do
- result = I18n.t :does_not_exist, :default => "%s interpolation syntax is deprecated", :value => 'this'
- assert_equal result, "this interpolation syntax is deprecated"
- end
- end
-
- def test_percent_s_interpolation_syntax_in_error_messages_is_deprecated
- assert_deprecated('using %s in messages') do
- I18n.t :does_not_exist, :default => "%s interpolation syntax is deprected", :value => 'this'
- end
- end
-
- def test_percent_d_interpolation_syntax_in_error_messages_still_works
- ActiveSupport::Deprecation.silence do
- result = I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprecated", :count => 2
- assert_equal result, "2 interpolation syntaxes are deprecated"
- end
- end
-
- def test_percent_d_interpolation_syntax_in_error_messages_is_deprecated
- assert_deprecated('using %d in messages') do
- I18n.t :does_not_exist, :default => "%d interpolation syntaxes are deprected", :count => 2
+ def test_percent_d_interpolation_syntax_in_error_messages_was_deprecated
+ assert_not_deprecated do
+ default = "%d interpolation syntaxes are deprecated"
+ assert_equal default, I18n.t(:does_not_exist, :default => default, :count => 2)
end
end
diff --git a/activerecord/test/fixtures/people.yml b/activerecord/test/fixtures/people.yml
index 3babb1fe59..123673a2af 100644
--- a/activerecord/test/fixtures/people.yml
+++ b/activerecord/test/fixtures/people.yml
@@ -2,14 +2,17 @@ michael:
id: 1
first_name: Michael
primary_contact_id: 2
+ number1_fan_id: 3
gender: M
david:
id: 2
first_name: David
primary_contact_id: 3
+ number1_fan_id: 1
gender: M
susan:
id: 3
first_name: Susan
primary_contact_id: 2
- gender: F \ No newline at end of file
+ number1_fan_id: 1
+ gender: F
diff --git a/activerecord/test/models/company_in_module.rb b/activerecord/test/models/company_in_module.rb
index 7f02403d5a..3c34efbe16 100644
--- a/activerecord/test/models/company_in_module.rb
+++ b/activerecord/test/models/company_in_module.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/misc'
+
module MyApplication
module Business
class Company < ActiveRecord::Base
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index ec2f684a6e..57fa6418f1 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -10,6 +10,7 @@ class Person < ActiveRecord::Base
belongs_to :primary_contact, :class_name => 'Person'
has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id'
+ belongs_to :number1_fan, :class_name => 'Person'
named_scope :males, :conditions => { :gender => 'M' }
named_scope :females, :conditions => { :gender => 'F' }
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index a776cd974b..6e8813d8ab 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -1,4 +1,3 @@
-
ActiveRecord::Schema.define do
def except(adapter_names_to_exclude)
unless [adapter_names_to_exclude].flatten.include?(adapter_name)
@@ -325,6 +324,7 @@ ActiveRecord::Schema.define do
t.string :first_name, :null => false
t.references :primary_contact
t.string :gender, :limit => 1
+ t.references :number1_fan
t.integer :lock_version, :null => false, :default => 0
end
@@ -500,3 +500,7 @@ ActiveRecord::Schema.define do
execute "ALTER TABLE fk_test_has_fk ADD CONSTRAINT fk_name FOREIGN KEY (#{quote_column_name 'fk_id'}) REFERENCES #{quote_table_name 'fk_test_has_pk'} (#{quote_column_name 'id'})"
end
end
+
+Course.connection.create_table :courses, :force => true do |t|
+ t.column :name, :string, :null => false
+end
diff --git a/activerecord/test/schema/schema2.rb b/activerecord/test/schema/schema2.rb
deleted file mode 100644
index 8527f7ba8f..0000000000
--- a/activerecord/test/schema/schema2.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-ActiveRecord::Schema.define do
-
- Course.connection.create_table :courses, :force => true do |t|
- t.column :name, :string, :null => false
- end
-end
diff --git a/activeresource/Rakefile b/activeresource/Rakefile
index c3cde26b6c..eb5b1dd1ac 100644
--- a/activeresource/Rakefile
+++ b/activeresource/Rakefile
@@ -34,6 +34,13 @@ Rake::TestTask.new { |t|
t.verbose = true
t.warning = true
}
+task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
+ activesupport_path = "#{File.dirname(__FILE__)}/../activesupport/lib"
+ Dir.glob("test/**/*_test.rb").all? do |file|
+ system(ruby, "-Ilib:test:#{activesupport_path}", file)
+ end or raise "Failures"
+end
# Generate the RDoc documentation
diff --git a/activeresource/examples/simple.rb b/activeresource/examples/simple.rb
new file mode 100644
index 0000000000..b20ef61670
--- /dev/null
+++ b/activeresource/examples/simple.rb
@@ -0,0 +1,16 @@
+$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
+require 'active_resource'
+require 'active_resource/http_mock'
+require 'active_support/core_ext/hash/conversions'
+
+ActiveSupport::XmlMini.backend = ENV['XMLMINI'] || 'REXML'
+ActiveResource::HttpMock.respond_to do |mock|
+ mock.get '/people/1.xml', {}, { :id => 1, :name => 'bob' }.to_xml(:root => 'person')
+end
+
+class Person < ActiveResource::Base
+ self.site = 'http://localhost/'
+end
+
+bob = Person.find(1)
+puts bob.inspect
diff --git a/activeresource/lib/active_resource/base.rb b/activeresource/lib/active_resource/base.rb
index 8a1236c9a8..dc24e713ff 100644
--- a/activeresource/lib/active_resource/base.rb
+++ b/activeresource/lib/active_resource/base.rb
@@ -1,8 +1,10 @@
+require 'active_support'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/class/inheritable_attributes'
require 'active_support/core_ext/module/attr_accessor_with_default'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/aliasing'
+require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/misc'
require 'set'
@@ -1027,7 +1029,7 @@ module ActiveResource
private
# Tries to find a resource for a given collection name; if it fails, then the resource is created
def find_or_create_resource_for_collection(name)
- find_or_create_resource_for(name.to_s.singularize)
+ find_or_create_resource_for(ActiveSupport::Inflector.singularize(name.to_s))
end
# Tries to find a resource in a non empty list of nested modules
diff --git a/activeresource/test/base/custom_methods_test.rb b/activeresource/test/base/custom_methods_test.rb
index 61887f4ec7..2d81549a65 100644
--- a/activeresource/test/base/custom_methods_test.rb
+++ b/activeresource/test/base/custom_methods_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'fixtures/person'
require 'fixtures/street_address'
+require 'active_support/core_ext/hash/conversions'
class CustomMethodsTest < Test::Unit::TestCase
def setup
diff --git a/activeresource/test/base/load_test.rb b/activeresource/test/base/load_test.rb
index cd2103acb7..035bd965c2 100644
--- a/activeresource/test/base/load_test.rb
+++ b/activeresource/test/base/load_test.rb
@@ -2,6 +2,7 @@ require 'abstract_unit'
require "fixtures/person"
require "fixtures/street_address"
require 'active_support/core_ext/symbol'
+require 'active_support/core_ext/hash/conversions'
module Highrise
class Note < ActiveResource::Base
diff --git a/activeresource/test/base_test.rb b/activeresource/test/base_test.rb
index a6cef6b2ae..82d3b2ae96 100644
--- a/activeresource/test/base_test.rb
+++ b/activeresource/test/base_test.rb
@@ -3,6 +3,7 @@ require "fixtures/person"
require "fixtures/customer"
require "fixtures/street_address"
require "fixtures/beast"
+require 'active_support/core_ext/hash/conversions'
class BaseTest < Test::Unit::TestCase
def setup
diff --git a/activesupport/Rakefile b/activesupport/Rakefile
index a4e8200a43..c3ea09d424 100644
--- a/activesupport/Rakefile
+++ b/activesupport/Rakefile
@@ -22,8 +22,8 @@ Rake::TestTask.new { |t|
t.warning = true
}
task :isolated_test do
+ ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
Dir['test/**/*_test.rb'].all? do |file|
- ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
system(ruby, '-Ilib:test', file)
end or raise "Failures"
end
diff --git a/activesupport/lib/active_support/core_ext/object/conversions.rb b/activesupport/lib/active_support/core_ext/object/conversions.rb
index 278b856c45..638f0decc1 100644
--- a/activesupport/lib/active_support/core_ext/object/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/object/conversions.rb
@@ -1,3 +1,6 @@
+require 'active_support/core_ext/array/conversions'
+require 'active_support/core_ext/hash/conversions'
+
class Object
# Alias of <tt>to_s</tt>.
def to_param
diff --git a/activesupport/lib/active_support/json.rb b/activesupport/lib/active_support/json.rb
index 5072992cdf..1e8ded12da 100644
--- a/activesupport/lib/active_support/json.rb
+++ b/activesupport/lib/active_support/json.rb
@@ -40,9 +40,15 @@ module ActiveSupport
end
class << self
- attr_reader :backend
delegate :decode, :to => :backend
-
+
+ def backend
+ @backend || begin
+ self.backend = defined?(::JSON) ? "JSONGem" : "Yaml"
+ @backend
+ end
+ end
+
def backend=(name)
if name.is_a?(Module)
@backend = name
@@ -77,6 +83,5 @@ module ActiveSupport
end
ActiveSupport.escape_html_entities_in_json = true
-ActiveSupport::JSON.backend = 'Yaml'
require 'active_support/json/encoding'
diff --git a/activesupport/lib/active_support/json/backends/jsongem.rb b/activesupport/lib/active_support/json/backends/jsongem.rb
index de847e30a3..649e6301d1 100644
--- a/activesupport/lib/active_support/json/backends/jsongem.rb
+++ b/activesupport/lib/active_support/json/backends/jsongem.rb
@@ -1,13 +1,18 @@
+require 'json' unless defined?(JSON)
+
module ActiveSupport
module JSON
- ParseError = ::JSON::ParserError
+ ParseError = ::JSON::ParserError unless const_defined?(:ParseError)
module Backends
module JSONGem
extend self
- # Converts a JSON string into a Ruby object.
+ # Parses a JSON string or IO and convert it into an object
def decode(json)
+ if json.respond_to?(:read)
+ json = json.read
+ end
data = ::JSON.parse(json)
if ActiveSupport.parse_json_times
convert_dates_from(data)
diff --git a/activesupport/lib/active_support/json/backends/yaml.rb b/activesupport/lib/active_support/json/backends/yaml.rb
index c7db508c23..667016f45d 100644
--- a/activesupport/lib/active_support/json/backends/yaml.rb
+++ b/activesupport/lib/active_support/json/backends/yaml.rb
@@ -2,15 +2,20 @@ require 'active_support/core_ext/string/starts_ends_with'
module ActiveSupport
module JSON
- class ParseError < StandardError
+ unless const_defined?(:ParseError)
+ class ParseError < StandardError
+ end
end
module Backends
module Yaml
extend self
- # Converts a JSON string into a Ruby object.
+ # Parses a JSON string or IO and converts it into an object
def decode(json)
+ if json.respond_to?(:read)
+ json = json.read
+ end
YAML.load(convert_json_to_yaml(json))
rescue ArgumentError => e
raise ParseError, "Invalid JSON string"
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index edf626802a..fa6db683d4 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/metaclass'
+require 'active_support/core_ext/module/aliasing'
module ActiveSupport
module SafelyMemoizable
diff --git a/activesupport/lib/active_support/xml_mini/jdom.rb b/activesupport/lib/active_support/xml_mini/jdom.rb
index d795d55690..1cd714d864 100644
--- a/activesupport/lib/active_support/xml_mini/jdom.rb
+++ b/activesupport/lib/active_support/xml_mini/jdom.rb
@@ -24,15 +24,19 @@ module ActiveSupport
node_type_map = {}
NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
- # Parse an XML Document string into a simple hash using Java's jdom.
- # string::
- # XML Document string to parse
- def parse(string)
- if string.blank?
+ # Parse an XML Document string or IO into a simple hash using Java's jdom.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
+ if data.blank?
{}
else
@dbf = DocumentBuilderFactory.new_instance
- xml_string_reader = StringReader.new(string)
+ xml_string_reader = StringReader.new(data)
xml_input_source = InputSource.new(xml_string_reader)
doc = @dbf.new_document_builder.parse(xml_input_source)
merge_element!({}, doc.document_element)
diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb
index 370205409a..d4c4dc7be5 100644
--- a/activesupport/lib/active_support/xml_mini/libxml.rb
+++ b/activesupport/lib/active_support/xml_mini/libxml.rb
@@ -5,16 +5,20 @@ module ActiveSupport
module XmlMini_LibXML #:nodoc:
extend self
- # Parse an XML Document string into a simple hash using libxml.
- # string::
- # XML Document string to parse
- def parse(string)
+ # Parse an XML Document string or IO into a simple hash using libxml.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
LibXML::XML.default_keep_blanks = false
- if string.blank?
+ if data.blank?
{}
else
- LibXML::XML::Parser.string(string.strip).parse.to_hash
+ LibXML::XML::Parser.string(data.strip).parse.to_hash
end
end
diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb
index 8f9676e4f6..7337c143c9 100644
--- a/activesupport/lib/active_support/xml_mini/nokogiri.rb
+++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb
@@ -5,14 +5,18 @@ module ActiveSupport
module XmlMini_Nokogiri #:nodoc:
extend self
- # Parse an XML Document string into a simple hash using libxml / nokogiri.
- # string::
- # XML Document string to parse
- def parse(string)
- if string.blank?
+ # Parse an XML Document string or IO into a simple hash using libxml / nokogiri.
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
+ if data.blank?
{}
else
- doc = Nokogiri::XML(string)
+ doc = Nokogiri::XML(data)
raise doc.errors.first if doc.errors.length > 0
doc.to_hash
end
diff --git a/activesupport/lib/active_support/xml_mini/rexml.rb b/activesupport/lib/active_support/xml_mini/rexml.rb
index 5033210aae..1184d2d6c9 100644
--- a/activesupport/lib/active_support/xml_mini/rexml.rb
+++ b/activesupport/lib/active_support/xml_mini/rexml.rb
@@ -7,16 +7,20 @@ module ActiveSupport
CONTENT_KEY = '__content__'.freeze
- # Parse an XML Document string into a simple hash
+ # Parse an XML Document string or IO into a simple hash
#
# Same as XmlSimple::xml_in but doesn't shoot itself in the foot,
# and uses the defaults from ActiveSupport
#
- # string::
- # XML Document string to parse
- def parse(string)
+ # data::
+ # XML Document string or IO to parse
+ def parse(data)
+ if data.respond_to?(:read)
+ data = data.read
+ end
+
require 'rexml/document' unless defined?(REXML::Document)
- doc = REXML::Document.new(string)
+ doc = REXML::Document.new(data)
merge_element!({}, doc.root)
end
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index 7e1bfcca84..09fd0d09ba 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -36,6 +36,9 @@ class TestJSONDecoding < ActiveSupport::TestCase
%q({"b":["\u003ci\u003e","\u003cb\u003e","\u003cu\u003e"]}) => {'b' => ["<i>","<b>","<u>"]}
}
+ # load the default JSON backend
+ ActiveSupport::JSON.backend
+
backends = %w(Yaml)
begin
gem 'json', '>= 1.1'
diff --git a/activesupport/test/xml_mini/nokogiri_engine_test.rb b/activesupport/test/xml_mini/nokogiri_engine_test.rb
index 886a9d1aba..7c3a591e63 100644
--- a/activesupport/test/xml_mini/nokogiri_engine_test.rb
+++ b/activesupport/test/xml_mini/nokogiri_engine_test.rb
@@ -148,6 +148,19 @@ class NokogiriEngineTest < Test::Unit::TestCase
eoxml
end
+ def test_parse_from_io
+ io = StringIO.new(<<-eoxml)
+ <root>
+ good
+ <products>
+ hello everyone
+ </products>
+ morning
+ </root>
+ eoxml
+ XmlMini.parse(io)
+ end
+
private
def assert_equal_rexml(xml)
hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
diff --git a/activesupport/test/xml_mini/rexml_engine_test.rb b/activesupport/test/xml_mini/rexml_engine_test.rb
index a412d8ca05..57bb35254a 100644
--- a/activesupport/test/xml_mini/rexml_engine_test.rb
+++ b/activesupport/test/xml_mini/rexml_engine_test.rb
@@ -12,4 +12,18 @@ class REXMLEngineTest < Test::Unit::TestCase
XmlMini.backend = 'REXML'
assert_equal XmlMini_REXML, XmlMini.backend
end
+
+ def test_parse_from_io
+ XmlMini.backend = 'REXML'
+ io = StringIO.new(<<-eoxml)
+ <root>
+ good
+ <products>
+ hello everyone
+ </products>
+ morning
+ </root>
+ eoxml
+ XmlMini.parse(io)
+ end
end
diff --git a/railties/Rakefile b/railties/Rakefile
index 4247742664..69c1ca762a 100644
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -2,7 +2,6 @@ require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
-require 'rake/contrib/rubyforgepublisher'
require 'date'
require 'rbconfig'
@@ -32,6 +31,7 @@ task :test do
system(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
end or raise "Failures"
end
+task :isolated_test => :test
Rake::TestTask.new("regular_test") do |t|
t.libs << 'test' << "#{File.dirname(__FILE__)}/../activesupport/lib"
@@ -249,7 +249,7 @@ def copy_with_rewritten_ruby_path(src_file, dest_file)
end
desc 'Generate guides (for authors), use ONLY=foo to process just "foo.textile"'
-task :guides do
+task :generate_guides do
ENV["WARN_BROKEN_LINKS"] = "1" # authors can't disable this
ruby "guides/rails_guides.rb"
end
@@ -298,6 +298,7 @@ PKG_FILES = FileList[
'doc/**/*',
'dispatches/**/*',
'environments/**/*',
+ 'guides/**/*',
'helpers/**/*',
'generators/**/*',
'html/**/*',
@@ -324,7 +325,7 @@ spec = Gem::Specification.new do |s|
s.rdoc_options << '--exclude' << '.'
s.has_rdoc = false
- s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
+ s.files = PKG_FILES.to_a.delete_if {|f| f =~ %r{\.svn|guides/output}}
s.require_path = 'lib'
s.bindir = "bin" # Use these for applications.
s.executables = ["rails"]
@@ -344,12 +345,14 @@ end
# Publishing -------------------------------------------------------
desc "Publish the rails gem"
task :pgem => [:gem] do
+ require 'rake/contrib/sshpublisher'
Rake::SshFilePublisher.new("gems.rubyonrails.org", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh gems.rubyonrails.org '/u/sites/gems/gemupdate.sh'`
end
desc "Publish the guides"
-task :pguides => :guides do
+task :pguides => :generate_guides do
+ require 'rake/contrib/sshpublisher'
mkdir_p 'pkg'
`tar -czf pkg/guides.gz guides/output`
Rake::SshFilePublisher.new("web.rubyonrails.org", "/u/sites/guides.rubyonrails.org/public", "pkg", "guides.gz").upload
@@ -358,6 +361,7 @@ end
desc "Publish the release files to RubyForge."
task :release => [ :package ] do
+ require 'rake/contrib/rubyforgepublisher'
require 'rubyforge'
packages = %w( gem ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
diff --git a/railties/builtin/rails_info/rails/info.rb b/railties/builtin/rails_info/rails/info.rb
index 0dd1c090c1..fdacc469f5 100644
--- a/railties/builtin/rails_info/rails/info.rb
+++ b/railties/builtin/rails_info/rails/info.rb
@@ -1,9 +1,13 @@
+require "active_support/core_ext/object/misc"
+require "cgi"
+require "active_support/core_ext/cgi"
+
module Rails
module Info
mattr_accessor :properties
class << (@@properties = [])
def names
- map &:first
+ map {|val| val.first }
end
def value_for(property_name)
@@ -53,7 +57,7 @@ module Rails
alias inspect to_s
def to_html
- returning table = '<table>' do
+ (table = '<table>').tap do
properties.each do |(name, value)|
table << %(<tr><td class="name">#{CGI.escapeHTML(name.to_s)}</td>)
formatted_value = if value.kind_of?(Array)
@@ -108,7 +112,7 @@ module Rails
end
property 'Middleware' do
- ActionController::Dispatcher.middleware.active.map(&:inspect)
+ ActionController::Dispatcher.middleware.active.map {|middle| middle.inspect }
end
# The Rails Git revision, if it's checked out into vendor/rails.
diff --git a/railties/configs/routes.rb b/railties/configs/routes.rb
index 4f3d9d22dd..ea14ce1bfc 100644
--- a/railties/configs/routes.rb
+++ b/railties/configs/routes.rb
@@ -37,7 +37,7 @@ ActionController::Routing::Routes.draw do |map|
# Install the default routes as the lowest priority.
# Note: These default routes make all actions in every controller accessible via GET requests. You should
- # consider removing the them or commenting them out if you're using named routes and resources.
+ # consider removing or commenting them out if you're using named routes and resources.
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
diff --git a/railties/lib/commands/performance/profiler.rb b/railties/lib/commands/performance/profiler.rb
index fd111bae87..7df840f197 100644
--- a/railties/lib/commands/performance/profiler.rb
+++ b/railties/lib/commands/performance/profiler.rb
@@ -29,7 +29,7 @@ begin
printer_class = RubyProf::FlatPrinter
end
printer = printer_class.new(results)
- printer.print($stderr, 0)
+ printer.print($stderr)
rescue LoadError
require "prof"
$stderr.puts 'Using the old ruby-prof extension.'
diff --git a/railties/lib/console_app.rb b/railties/lib/console_app.rb
index c944d49205..42bf50e01e 100644
--- a/railties/lib/console_app.rb
+++ b/railties/lib/console_app.rb
@@ -26,8 +26,7 @@ end
#reloads the environment
def reload!
puts "Reloading..."
- dispatcher = ActionController::Dispatcher.new
- dispatcher.cleanup_application
- dispatcher.reload_application
+ ActionController::Dispatcher.new
+ ActionController::Dispatcher.router.reload
true
end
diff --git a/railties/lib/initializer.rb b/railties/lib/initializer.rb
index 9d27488e8a..4c6de48a65 100644
--- a/railties/lib/initializer.rb
+++ b/railties/lib/initializer.rb
@@ -264,8 +264,8 @@ module Rails
# Action Pack, Action Mailer, and Active Resource) are loaded.
def require_frameworks
require 'active_support'
- require 'active_support/core/all'
configuration.frameworks.each { |framework| require(framework.to_s) }
+ require 'active_support/core/all'
rescue LoadError => e
# Re-raise as RuntimeError because Mongrel would swallow LoadError.
raise e.to_s
@@ -311,7 +311,7 @@ module Rails
end
def check_for_unbuilt_gems
- unbuilt_gems = @configuration.gems.select(&:frozen?).reject(&:built?)
+ 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
@@ -462,7 +462,7 @@ Run `rake gems:install` to install the missing gems.
if RAILS_CACHE.respond_to?(:middleware)
# Insert middleware to setup and teardown local cache for each request
- configuration.middleware.insert_after(:"ActionDispatch::Failsafe", RAILS_CACHE.middleware)
+ configuration.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware)
end
end
end
@@ -632,7 +632,6 @@ Run `rake gems:install` to install the missing gems.
return unless configuration.frameworks.include?(:action_controller)
require 'dispatcher' unless defined?(::Dispatcher)
Dispatcher.define_dispatcher_callbacks(configuration.cache_classes)
- Dispatcher.run_prepare_callbacks
end
def disable_dependency_loading
diff --git a/railties/lib/rails/plugin.rb b/railties/lib/rails/plugin.rb
index 0f924724cd..e66166306a 100644
--- a/railties/lib/rails/plugin.rb
+++ b/railties/lib/rails/plugin.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/kernel/reporting'
+
module Rails
# The Plugin class should be an object which provides the following methods:
#
diff --git a/railties/lib/rails/plugin/loader.rb b/railties/lib/rails/plugin/loader.rb
index 66e01d70da..bc22dfc591 100644
--- a/railties/lib/rails/plugin/loader.rb
+++ b/railties/lib/rails/plugin/loader.rb
@@ -24,7 +24,7 @@ module Rails
# Returns the plugins that are in engine-form (have an app/ directory)
def engines
- @engines ||= plugins.select(&:engine?)
+ @engines ||= plugins.select {|plugin| plugin.engine? }
end
# Returns all the plugins that could be found by the current locators.
@@ -66,7 +66,7 @@ module Rails
end
def engine_metal_paths
- engines.collect(&:metal_path)
+ engines.collect {|engine| engine.metal_path }
end
protected
@@ -79,18 +79,18 @@ module Rails
end
def add_engine_routing_configurations
- engines.select(&:routed?).collect(&:routing_file).each do |routing_file|
+ engines.select {|engine| engine.routed? }.map {|engine| engine.routing_file }.each do |routing_file|
ActionController::Routing::Routes.add_configuration_file(routing_file)
end
end
def add_engine_controller_paths
- ActionController::Routing.controller_paths += engines.collect(&:controller_path)
+ ActionController::Routing.controller_paths += engines.collect {|engine| engine.controller_path }
end
def add_engine_view_paths
# reverse it such that the last engine can overwrite view paths from the first, like with routes
- paths = ActionView::PathSet.new(engines.collect(&:view_path).reverse)
+ paths = ActionView::PathSet.new(engines.collect {|engine| engine.view_path }.reverse)
ActionController::Base.view_paths.concat(paths)
ActionMailer::Base.view_paths.concat(paths) if configuration.frameworks.include?(:action_mailer)
end
@@ -170,7 +170,7 @@ module Rails
# so we load all in alphabetical order. If it is an empty array, we load no plugins, if it is
# non empty, we load the named plugins in the order specified.
def registered_plugin_names
- configuration.plugins ? configuration.plugins.map(&:to_s) : nil
+ configuration.plugins ? configuration.plugins.map {|plugin| plugin.to_s } : nil
end
def loaded?(plugin_name)
diff --git a/railties/lib/rails/plugin/locator.rb b/railties/lib/rails/plugin/locator.rb
index a6fc388a8e..1057c004e0 100644
--- a/railties/lib/rails/plugin/locator.rb
+++ b/railties/lib/rails/plugin/locator.rb
@@ -25,7 +25,7 @@ module Rails
end
def plugin_names
- plugins.map(&:name)
+ plugins.map {|plugin| plugin.name }
end
end
diff --git a/railties/lib/rails_generator/generators/applications/app/template_runner.rb b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
index 3b49b1fa92..0e24d11950 100644
--- a/railties/lib/rails_generator/generators/applications/app/template_runner.rb
+++ b/railties/lib/rails_generator/generators/applications/app/template_runner.rb
@@ -227,7 +227,7 @@ module Rails
#
def generate(what, *args)
log 'generating', what
- argument = args.map(&:to_s).flatten.join(" ")
+ argument = args.map {|arg| arg.to_s }.flatten.join(" ")
in_root { run_ruby_script("script/generate #{what} #{argument}", false) }
end
diff --git a/railties/lib/rails_generator/generators/components/model/templates/model.rb b/railties/lib/rails_generator/generators/components/model/templates/model.rb
index 6fcf393bdf..0656b06dfe 100644
--- a/railties/lib/rails_generator/generators/components/model/templates/model.rb
+++ b/railties/lib/rails_generator/generators/components/model/templates/model.rb
@@ -1,5 +1,5 @@
class <%= class_name %> < ActiveRecord::Base
-<% attributes.select(&:reference?).each do |attribute| -%>
+<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
belongs_to :<%= attribute.name %>
<% end -%>
end
diff --git a/railties/lib/rails_generator/scripts.rb b/railties/lib/rails_generator/scripts.rb
index 9b1a99838a..3763b75dba 100644
--- a/railties/lib/rails_generator/scripts.rb
+++ b/railties/lib/rails_generator/scripts.rb
@@ -57,7 +57,7 @@ module Rails
usage << <<end_blurb
-More are available at http://wiki.rubyonrails.org/rails/pages/AvailableGenerators
+You can also install additional generators for your own use:
1. Download, for example, login_generator.zip
2. Unzip to directory #{Dir.user_home}/.rails/generators/login
to use the generator with all your Rails apps
diff --git a/railties/lib/tasks/gems.rake b/railties/lib/tasks/gems.rake
index 7cf7061f38..e496e1a04f 100644
--- a/railties/lib/tasks/gems.rake
+++ b/railties/lib/tasks/gems.rake
@@ -20,7 +20,7 @@ namespace :gems do
desc "Build any native extensions for unpacked gems"
task :build do
$gems_build_rake_task = true
- frozen_gems.each &:build
+ frozen_gems.each {|gem| gem.build }
end
namespace :build do
@@ -33,12 +33,12 @@ namespace :gems do
desc "Installs all required gems."
task :install => :base do
- current_gems.each &:install
+ current_gems.each {|gem| gem.install }
end
desc "Unpacks all required gems into vendor/gems."
task :unpack => :install do
- current_gems.each &:unpack
+ current_gems.each {|gem| gem.unpack }
end
namespace :unpack do
@@ -50,7 +50,7 @@ namespace :gems do
desc "Regenerate gem specifications in correct format."
task :refresh_specs => :base do
- current_gems.each &:refresh
+ current_gems.each {|gem| gem.refresh }
end
end
diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb
index ffd60ee662..0addcb8bf3 100644
--- a/railties/test/abstract_unit.rb
+++ b/railties/test/abstract_unit.rb
@@ -13,7 +13,6 @@ gem 'mocha', '>= 0.9.5'
require 'mocha'
require 'active_support'
-require 'active_support/core/all'
require 'active_support/test_case'
if defined?(RAILS_ROOT)
diff --git a/railties/test/plugin_test_helper.rb b/railties/test/plugin_test_helper.rb
index adb62de665..55d1a1fa96 100644
--- a/railties/test/plugin_test_helper.rb
+++ b/railties/test/plugin_test_helper.rb
@@ -3,7 +3,6 @@ $:.unshift File.dirname(__FILE__) + "/../../activesupport/lib"
require 'test/unit'
require 'active_support'
-require 'active_support/core/all'
require 'initializer'
require File.join(File.dirname(__FILE__), 'abstract_unit')
diff --git a/railties/test/rails_info_test.rb b/railties/test/rails_info_test.rb
index 971cba89d0..fdcc7a1ef6 100644
--- a/railties/test/rails_info_test.rb
+++ b/railties/test/rails_info_test.rb
@@ -14,6 +14,8 @@ unless defined?(Rails) && defined?(Rails::Info)
end
end
+require "active_support/core_ext/kernel/reporting"
+
class InfoTest < ActiveSupport::TestCase
def setup
Rails.send :remove_const, :Info
diff --git a/tools/profile_requires.rb b/tools/profile_requires
index 68d0de3d80..0fd11c7d41 100644..100755
--- a/tools/profile_requires.rb
+++ b/tools/profile_requires
@@ -1,7 +1,7 @@
#!/usr/bin/env ruby
# Example:
-# ruby -Iactivesupport/lib tools/profile_requires.rb active_support
-# ruby -Iactionpack/lib tools/profile_requires.rb action_controller
+# tools/profile_requires activesupport/lib/active_support.rb
+# tools/profile_requires activeresource/examples/simple.rb
abort 'Use REE so you can profile memory and object allocation' unless GC.respond_to?(:enable_stats)
GC.enable_stats
@@ -18,12 +18,14 @@ module TrackHeapGrowth
self.stats = []
def track_growth(file)
+ TrackHeapGrowth.stats << [file, TrackHeapGrowth.indent]
TrackHeapGrowth.indent += 1
heap_before, objects_before = GC.allocated_size, ObjectSpace.allocated_objects
result = nil
elapsed = Benchmark.realtime { result = yield }
heap_after, objects_after = GC.allocated_size, ObjectSpace.allocated_objects
TrackHeapGrowth.indent -= 1
+ TrackHeapGrowth.stats.pop if TrackHeapGrowth.stats.last.first == file
TrackHeapGrowth.stats << [file, TrackHeapGrowth.indent, elapsed, heap_after - heap_before, objects_after - objects_before] if result
result
end
@@ -69,7 +71,11 @@ if mode
end
end
-TrackHeapGrowth.stats.reverse_each do |file, indent, sec, bytes, objects|
- puts "%10.2f KB %10d obj %8.1f ms %s%s" % [bytes / 1024.0, objects, sec * 1000, ' ' * indent, file]
+TrackHeapGrowth.stats.each do |file, indent, sec, bytes, objects|
+ if sec
+ puts "%10.2f KB %10d obj %8.1f ms %s%s" % [bytes / 1024.0, objects, sec * 1000, ' ' * indent, file]
+ else
+ puts "#{' ' * (42 + indent)}#{file}"
+ end
end
puts "%10.2f KB %10d obj %8.1f ms %d KB RSS" % [usage, after_live_objects - before_live_objects, elapsed * 1000, after_rss - before_rss]