aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actioncable/test/channel/periodic_timers_test.rb9
-rw-r--r--actionmailer/lib/action_mailer/base.rb2
-rw-r--r--actionmailer/lib/action_mailer/inline_preview_interceptor.rb6
-rw-r--r--actionpack/CHANGELOG.md8
-rw-r--r--actionpack/lib/action_dispatch/journey/path/pattern.rb7
-rw-r--r--actionpack/lib/action_dispatch/journey/route.rb8
-rw-r--r--actionpack/lib/action_dispatch/journey/router.rb7
-rw-r--r--actionpack/lib/action_dispatch/middleware/callbacks.rb12
-rw-r--r--actionpack/lib/action_dispatch/middleware/reloader.rb50
-rw-r--r--actionpack/lib/action_dispatch/railtie.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb6
-rw-r--r--actionpack/test/dispatch/callbacks_test.rb18
-rw-r--r--actionpack/test/dispatch/reloader_test.rb129
-rw-r--r--actionview/lib/action_view/template/handlers/erb.rb2
-rw-r--r--actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb9
-rw-r--r--actionview/lib/action_view/template/resolver.rb4
-rw-r--r--actionview/lib/action_view/testing/resolvers.rb50
-rw-r--r--actionview/test/template/erb/deprecated_erubis_implementation_test.rb2
-rw-r--r--actionview/test/template/render_test.rb3
-rw-r--r--activejob/CHANGELOG.md4
-rw-r--r--activejob/lib/active_job/queue_adapters/test_adapter.rb10
-rw-r--r--activejob/test/cases/test_helper_test.rb11
-rw-r--r--activerecord/lib/active_record.rb3
-rw-r--r--activerecord/lib/active_record/associations/has_one_through_association.rb4
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb2
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_association.rb8
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb2
-rw-r--r--activerecord/lib/active_record/reflection.rb72
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb4
-rw-r--r--activerecord/test/cases/associations/eager_test.rb15
-rw-r--r--activerecord/test/cases/associations/has_one_through_associations_test.rb7
-rw-r--r--activerecord/test/cases/migrator_test.rb3
-rw-r--r--activerecord/test/cases/reflection_test.rb20
-rw-r--r--activesupport/lib/active_support/evented_file_update_checker.rb4
-rw-r--r--activesupport/lib/active_support/file_update_checker.rb4
-rw-r--r--activesupport/lib/active_support/number_helper.rb2
-rw-r--r--activesupport/test/dependencies_test.rb3
-rw-r--r--activesupport/test/file_update_checker_shared_tests.rb6
-rw-r--r--activesupport/test/reloader_test.rb14
-rw-r--r--activesupport/test/security_utils_test.rb7
-rw-r--r--activesupport/test/time_travel_test.rb3
-rw-r--r--guides/source/i18n.md29
-rw-r--r--railties/lib/rails/application/finisher.rb1
-rw-r--r--railties/lib/rails/application/routes_reloader.rb17
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/locales/en.yml10
-rw-r--r--railties/test/application/configuration_test.rb6
-rw-r--r--railties/test/application/mailer_previews_test.rb34
47 files changed, 357 insertions, 282 deletions
diff --git a/actioncable/test/channel/periodic_timers_test.rb b/actioncable/test/channel/periodic_timers_test.rb
index 0cc4992ef6..17a8e45a35 100644
--- a/actioncable/test/channel/periodic_timers_test.rb
+++ b/actioncable/test/channel/periodic_timers_test.rb
@@ -38,23 +38,26 @@ class ActionCable::Channel::PeriodicTimersTest < ActiveSupport::TestCase
test "disallow negative and zero periods" do
[ 0, 0.0, 0.seconds, -1, -1.seconds, "foo", :foo, Object.new ].each do |invalid|
- assert_raise ArgumentError, /Expected every:/ do
+ e = assert_raise ArgumentError do
ChatChannel.periodically :send_updates, every: invalid
end
+ assert_match(/Expected every:/, e.message)
end
end
test "disallow block and arg together" do
- assert_raise ArgumentError, /not both/ do
+ e = assert_raise ArgumentError do
ChatChannel.periodically(:send_updates, every: 1) { ping }
end
+ assert_match(/not both/, e.message)
end
test "disallow unknown args" do
[ "send_updates", Object.new, nil ].each do |invalid|
- assert_raise ArgumentError, /Expected a Symbol/ do
+ e = assert_raise ArgumentError do
ChatChannel.periodically invalid, every: 1
end
+ assert_match(/Expected a Symbol/, e.message)
end
end
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index c0c030ac3e..f02108a859 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -428,7 +428,7 @@ module ActionMailer
# * <tt>deliveries</tt> - Keeps an array of all the emails sent out through the Action Mailer with
# <tt>delivery_method :test</tt>. Most useful for unit and functional testing.
#
- # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>.
+ # * <tt>deliver_later_queue_name</tt> - The name of the queue used with <tt>deliver_later</tt>. Defaults to +mailers+.
class Base < AbstractController::Base
include DeliveryMethods
include Rescuable
diff --git a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
index 9087d335fa..980415afe0 100644
--- a/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
+++ b/actionmailer/lib/action_mailer/inline_preview_interceptor.rb
@@ -26,7 +26,7 @@ module ActionMailer
def transform! #:nodoc:
return message if html_part.blank?
- html_source.gsub!(PATTERN) do |match|
+ html_part.body = html_part.decoded.gsub(PATTERN) do |match|
if part = find_part(match[9..-2])
%[src="#{data_url(part)}"]
else
@@ -46,10 +46,6 @@ module ActionMailer
@html_part ||= message.html_part
end
- def html_source
- html_part.body.raw_source
- end
-
def data_url(part)
"data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}"
end
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 425a9d9e87..a7a4aabc98 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,3 +1,11 @@
+* Remove deprecated `.to_prepare`, `.to_cleanup`, `.prepare!` and `.cleanup!` from `ActionDispatch::Reloader`.
+
+ *Rafael Mendonça França*
+
+* Remove deprecated `ActionDispatch::Callbacks.to_prepare` and `ActionDispatch::Callbacks.to_cleanup`.
+
+ *Rafael Mendonça França*
+
* Remove deprecated `ActionController::Metal.call`.
*Rafael Mendonça França*
diff --git a/actionpack/lib/action_dispatch/journey/path/pattern.rb b/actionpack/lib/action_dispatch/journey/path/pattern.rb
index 0902b9233e..cf0108ec32 100644
--- a/actionpack/lib/action_dispatch/journey/path/pattern.rb
+++ b/actionpack/lib/action_dispatch/journey/path/pattern.rb
@@ -31,6 +31,13 @@ module ActionDispatch
Visitors::FormatBuilder.new.accept(spec)
end
+ def eager_load!
+ required_names
+ offsets
+ to_regexp
+ nil
+ end
+
def ast
@spec.find_all(&:symbol?).each do |node|
re = @requirements[node.to_sym]
diff --git a/actionpack/lib/action_dispatch/journey/route.rb b/actionpack/lib/action_dispatch/journey/route.rb
index f2ac4818d8..927fd369c4 100644
--- a/actionpack/lib/action_dispatch/journey/route.rb
+++ b/actionpack/lib/action_dispatch/journey/route.rb
@@ -73,6 +73,14 @@ module ActionDispatch
@internal = internal
end
+ def eager_load!
+ path.eager_load!
+ ast
+ parts
+ required_defaults
+ nil
+ end
+
def ast
@decorated_ast ||= begin
decorated_ast = path.ast
diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb
index 084ae9325e..d55e1399e4 100644
--- a/actionpack/lib/action_dispatch/journey/router.rb
+++ b/actionpack/lib/action_dispatch/journey/router.rb
@@ -22,6 +22,13 @@ module ActionDispatch
@routes = routes
end
+ def eager_load!
+ # Eagerly trigger the simulator's initialization so
+ # it doesn't happen during a request cycle.
+ simulator
+ nil
+ end
+
def serve(req)
find_routes(req).each do |match, parameters, route|
set_params = req.path_parameters
diff --git a/actionpack/lib/action_dispatch/middleware/callbacks.rb b/actionpack/lib/action_dispatch/middleware/callbacks.rb
index fef246532b..ff129cf96a 100644
--- a/actionpack/lib/action_dispatch/middleware/callbacks.rb
+++ b/actionpack/lib/action_dispatch/middleware/callbacks.rb
@@ -1,4 +1,3 @@
-
module ActionDispatch
# Provides callbacks to be executed before and after dispatching the request.
class Callbacks
@@ -7,17 +6,6 @@ module ActionDispatch
define_callbacks :call
class << self
- def to_prepare(*args, &block)
- ActiveSupport::Reloader.to_prepare(*args, &block)
- end
-
- def to_cleanup(*args, &block)
- ActiveSupport::Reloader.to_complete(*args, &block)
- end
-
- deprecate to_prepare: "use ActiveSupport::Reloader.to_prepare instead",
- to_cleanup: "use ActiveSupport::Reloader.to_complete instead"
-
def before(*args, &block)
set_callback(:call, :before, *args, &block)
end
diff --git a/actionpack/lib/action_dispatch/middleware/reloader.rb b/actionpack/lib/action_dispatch/middleware/reloader.rb
index 90c64037aa..6d64b1424b 100644
--- a/actionpack/lib/action_dispatch/middleware/reloader.rb
+++ b/actionpack/lib/action_dispatch/middleware/reloader.rb
@@ -1,54 +1,10 @@
module ActionDispatch
- # ActionDispatch::Reloader provides prepare and cleanup callbacks,
- # intended to assist with code reloading during development.
- #
- # Prepare callbacks are run before each request, and cleanup callbacks
- # after each request. In this respect they are analogs of ActionDispatch::Callback's
- # before and after callbacks. However, cleanup callbacks are not called until the
- # request is fully complete -- that is, after #close has been called on
- # the response body. This is important for streaming responses such as the
- # following:
- #
- # self.response_body = -> (response, output) do
- # # code here which refers to application models
- # end
- #
- # Cleanup callbacks will not be called until after the response_body lambda
- # is evaluated, ensuring that it can refer to application models and other
- # classes before they are unloaded.
+ # ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader
+ # callbacks, intended to assist with code reloading during development.
#
# By default, ActionDispatch::Reloader is included in the middleware stack
# only in the development environment; specifically, when +config.cache_classes+
- # is false. Callbacks may be registered even when it is not included in the
- # middleware stack, but are executed only when <tt>ActionDispatch::Reloader.prepare!</tt>
- # or <tt>ActionDispatch::Reloader.cleanup!</tt> are called manually.
- #
+ # is false.
class Reloader < Executor
- def self.to_prepare(*args, &block)
- ActiveSupport::Reloader.to_prepare(*args, &block)
- end
-
- def self.to_cleanup(*args, &block)
- ActiveSupport::Reloader.to_complete(*args, &block)
- end
-
- def self.prepare!
- default_reloader.prepare!
- end
-
- def self.cleanup!
- default_reloader.reload!
- end
-
- class << self
- attr_accessor :default_reloader # :nodoc:
-
- deprecate to_prepare: "use ActiveSupport::Reloader.to_prepare instead",
- to_cleanup: "use ActiveSupport::Reloader.to_complete instead",
- prepare!: "use Rails.application.reloader.prepare! instead",
- cleanup!: "use Rails.application.reloader.reload! instead of cleanup + prepare"
- end
-
- self.default_reloader = ActiveSupport::Reloader
end
end
diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb
index 48cc91bbfa..16a18a7f25 100644
--- a/actionpack/lib/action_dispatch/railtie.rb
+++ b/actionpack/lib/action_dispatch/railtie.rb
@@ -39,8 +39,6 @@ module ActionDispatch
config.action_dispatch.always_write_cookie = Rails.env.development? if config.action_dispatch.always_write_cookie.nil?
ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
- ActionDispatch::Reloader.default_reloader = app.reloader
-
ActionDispatch.test_app = app
end
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 5853adb110..5b873aeab7 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -349,6 +349,12 @@ module ActionDispatch
@formatter = Journey::Formatter.new self
end
+ def eager_load!
+ router.eager_load!
+ routes.each(&:eager_load!)
+ nil
+ end
+
def relative_url_root
@config.relative_url_root
end
diff --git a/actionpack/test/dispatch/callbacks_test.rb b/actionpack/test/dispatch/callbacks_test.rb
index 57e21a22c6..29a5dfc0ad 100644
--- a/actionpack/test/dispatch/callbacks_test.rb
+++ b/actionpack/test/dispatch/callbacks_test.rb
@@ -35,24 +35,6 @@ class DispatcherTest < ActiveSupport::TestCase
assert_equal 6, Foo.b
end
- def test_to_prepare_and_cleanup_delegation
- prepared = cleaned = false
- assert_deprecated do
- ActionDispatch::Callbacks.to_prepare { prepared = true }
- ActionDispatch::Callbacks.to_prepare { cleaned = true }
- end
-
- assert_deprecated do
- ActionDispatch::Reloader.prepare!
- end
- assert prepared
-
- assert_deprecated do
- ActionDispatch::Reloader.cleanup!
- end
- assert cleaned
- end
-
private
def dispatch(&block)
diff --git a/actionpack/test/dispatch/reloader_test.rb b/actionpack/test/dispatch/reloader_test.rb
index db68549b84..797430c85a 100644
--- a/actionpack/test/dispatch/reloader_test.rb
+++ b/actionpack/test/dispatch/reloader_test.rb
@@ -1,32 +1,11 @@
require "abstract_unit"
class ReloaderTest < ActiveSupport::TestCase
- Reloader = ActionDispatch::Reloader
-
teardown do
ActiveSupport::Reloader.reset_callbacks :prepare
ActiveSupport::Reloader.reset_callbacks :complete
end
- def test_prepare_callbacks
- a = b = c = nil
- assert_deprecated do
- Reloader.to_prepare { |*args| a = b = c = 1 }
- Reloader.to_prepare { |*args| b = c = 2 }
- Reloader.to_prepare { |*args| c = 3 }
- end
-
- # Ensure to_prepare callbacks are not run when defined
- assert_nil a || b || c
-
- # Run callbacks
- call_and_return_body
-
- assert_equal 1, a
- assert_equal 2, b
- assert_equal 3, c
- end
-
class MyBody < Array
def initialize(&block)
@on_close = block
@@ -45,6 +24,23 @@ class ReloaderTest < ActiveSupport::TestCase
end
end
+ def test_prepare_callbacks
+ a = b = c = nil
+ reloader.to_prepare { |*args| a = b = c = 1 }
+ reloader.to_prepare { |*args| b = c = 2 }
+ reloader.to_prepare { |*args| c = 3 }
+
+ # Ensure to_prepare callbacks are not run when defined
+ assert_nil a || b || c
+
+ # Run callbacks
+ call_and_return_body
+
+ assert_equal 1, a
+ assert_equal 2, b
+ assert_equal 3, c
+ end
+
def test_returned_body_object_always_responds_to_close
body = call_and_return_body
assert_respond_to body, :close
@@ -62,15 +58,12 @@ class ReloaderTest < ActiveSupport::TestCase
def test_condition_specifies_when_to_reload
i, j = 0, 0, 0, 0
- assert_deprecated do
- Reloader.to_prepare { |*args| i += 1 }
- Reloader.to_cleanup { |*args| j += 1 }
- end
- x = Class.new(ActiveSupport::Reloader)
- x.check = lambda { i < 3 }
+ reloader = reloader(lambda { i < 3 })
+ reloader.to_prepare { |*args| i += 1 }
+ reloader.to_complete { |*args| j += 1 }
- app = Reloader.new(lambda { |env| [200, {}, []] }, x)
+ app = middleware(lambda { |env| [200, {}, []] }, reloader)
5.times do
resp = app.call({})
resp[2].close
@@ -115,24 +108,20 @@ class ReloaderTest < ActiveSupport::TestCase
assert_respond_to body, :bar
end
- def test_cleanup_callbacks_are_called_when_body_is_closed
- cleaned = false
- assert_deprecated do
- Reloader.to_cleanup { cleaned = true }
- end
+ def test_complete_callbacks_are_called_when_body_is_closed
+ completed = false
+ reloader.to_complete { completed = true }
body = call_and_return_body
- assert !cleaned
+ assert !completed
body.close
- assert cleaned
+ assert completed
end
def test_prepare_callbacks_arent_called_when_body_is_closed
prepared = false
- assert_deprecated do
- Reloader.to_prepare { prepared = true }
- end
+ reloader.to_prepare { prepared = true }
body = call_and_return_body
prepared = false
@@ -141,45 +130,9 @@ class ReloaderTest < ActiveSupport::TestCase
assert !prepared
end
- def test_manual_reloading
- prepared = cleaned = false
- assert_deprecated do
- Reloader.to_prepare { prepared = true }
- Reloader.to_cleanup { cleaned = true }
- end
-
- assert_deprecated do
- Reloader.prepare!
- end
- assert prepared
- assert !cleaned
-
- prepared = cleaned = false
- assert_deprecated do
- Reloader.cleanup!
- end
- assert prepared
- assert cleaned
- end
-
- def test_prepend_prepare_callback
- i = 10
- assert_deprecated do
- Reloader.to_prepare { i += 1 }
- Reloader.to_prepare(prepend: true) { i = 0 }
- end
-
- assert_deprecated do
- Reloader.prepare!
- end
- assert_equal 1, i
- end
-
- def test_cleanup_callbacks_are_called_on_exceptions
- cleaned = false
- assert_deprecated do
- Reloader.to_cleanup { cleaned = true }
- end
+ def test_complete_callbacks_are_called_on_exceptions
+ completed = false
+ reloader.to_complete { completed = true }
begin
call_and_return_body do
@@ -188,16 +141,26 @@ class ReloaderTest < ActiveSupport::TestCase
rescue
end
- assert cleaned
+ assert completed
end
private
def call_and_return_body(&block)
- x = Class.new(ActiveSupport::Reloader)
- x.check = lambda { true }
+ app = middleware(block || proc { [200, {}, "response"] })
+ _, _, body = app.call("rack.input" => StringIO.new(""))
+ body
+ end
+
+ def middleware(inner_app, reloader = reloader())
+ ActionDispatch::Reloader.new(inner_app, reloader)
+ end
+
+ def reloader(check = lambda { true })
+ @reloader ||= begin
+ reloader = Class.new(ActiveSupport::Reloader)
+ reloader.check = check
+ reloader
+ end
- @response ||= "response"
- @reloader ||= Reloader.new(block || proc { [200, {}, @response] }, x)
- @reloader.call("rack.input" => StringIO.new(""))[2]
end
end
diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb
index cee5408aa9..58c7fd1a88 100644
--- a/actionview/lib/action_view/template/handlers/erb.rb
+++ b/actionview/lib/action_view/template/handlers/erb.rb
@@ -1,7 +1,7 @@
module ActionView
class Template
module Handlers
- Erubis = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("Erubis", "ActionView::Template::Handlers::ERB::Erubis", message: "ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead.")
+ autoload :Erubis, "action_view/template/handlers/erb/deprecated_erubis"
class ERB
autoload :Erubi, "action_view/template/handlers/erb/erubi"
diff --git a/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb b/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb
new file mode 100644
index 0000000000..427ea20064
--- /dev/null
+++ b/actionview/lib/action_view/template/handlers/erb/deprecated_erubis.rb
@@ -0,0 +1,9 @@
+::ActiveSupport::Deprecation.warn("ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead.")
+
+module ActionView
+ class Template
+ module Handlers
+ Erubis = ERB::Erubis
+ end
+ end
+end
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index 924de3da06..d3905b5f23 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -226,7 +226,7 @@ module ActionView
template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
template_paths.map do |template|
- handler, format, variant = extract_handler_and_format_and_variant(template, formats)
+ handler, format, variant = extract_handler_and_format_and_variant(template)
contents = File.binread(template)
Template.new(contents, File.expand_path(template), handler,
@@ -289,7 +289,7 @@ module ActionView
# Extract handler, formats and variant from path. If a format cannot be found neither
# from the path, or the handler, we should return the array of formats given
# to the resolver.
- def extract_handler_and_format_and_variant(path, default_formats)
+ def extract_handler_and_format_and_variant(path)
pieces = File.basename(path).split(".".freeze)
pieces.shift
diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb
index f4a7a9138c..3188526b63 100644
--- a/actionview/lib/action_view/testing/resolvers.rb
+++ b/actionview/lib/action_view/testing/resolvers.rb
@@ -17,35 +17,35 @@ module ActionView #:nodoc:
@hash.keys.join(", ")
end
- private
-
- def query(path, exts, formats, _)
- query = ""
- EXTENSIONS.each_key do |ext|
- query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
- end
- query = /^(#{Regexp.escape(path)})#{query}$/
-
- templates = []
- @hash.each do |_path, array|
- source, updated_at = array
- next unless query.match?(_path)
- handler, format, variant = extract_handler_and_format_and_variant(_path, formats)
- templates << Template.new(source, _path, handler,
- virtual_path: path.virtual,
- format: format,
- variant: variant,
- updated_at: updated_at
- )
+ private
+
+ def query(path, exts, _, _)
+ query = ""
+ EXTENSIONS.each_key do |ext|
+ query << "(" << exts[ext].map { |e| e && Regexp.escape(".#{e}") }.join("|") << "|)"
+ end
+ query = /^(#{Regexp.escape(path)})#{query}$/
+
+ templates = []
+ @hash.each do |_path, array|
+ source, updated_at = array
+ next unless query.match?(_path)
+ handler, format, variant = extract_handler_and_format_and_variant(_path)
+ templates << Template.new(source, _path, handler,
+ virtual_path: path.virtual,
+ format: format,
+ variant: variant,
+ updated_at: updated_at
+ )
+ end
+
+ templates.sort_by { |t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
end
-
- templates.sort_by { |t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
- end
end
class NullResolver < PathResolver
- def query(path, exts, formats, _)
- handler, format, variant = extract_handler_and_format_and_variant(path, formats)
+ def query(path, exts, _, _)
+ handler, format, variant = extract_handler_and_format_and_variant(path)
[ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: format, variant: variant)]
end
end
diff --git a/actionview/test/template/erb/deprecated_erubis_implementation_test.rb b/actionview/test/template/erb/deprecated_erubis_implementation_test.rb
index 4a130e6c33..aaf99f85c0 100644
--- a/actionview/test/template/erb/deprecated_erubis_implementation_test.rb
+++ b/actionview/test/template/erb/deprecated_erubis_implementation_test.rb
@@ -5,6 +5,8 @@ module ERBTest
test "Erubis implementation is deprecated" do
assert_deprecated "ActionView::Template::Handlers::Erubis is deprecated and will be removed from Rails 5.2. Switch to ActionView::Template::Handlers::ERB::Erubi instead." do
assert_equal "ActionView::Template::Handlers::ERB::Erubis", ActionView::Template::Handlers::Erubis.to_s
+
+ assert_nothing_raised { Class.new(ActionView::Template::Handlers::Erubis) }
end
end
end
diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb
index d189b2aa87..7c5a53b98b 100644
--- a/actionview/test/template/render_test.rb
+++ b/actionview/test/template/render_test.rb
@@ -393,8 +393,7 @@ module RenderTestCases
assert_equal :partial_name_local_variable, exception.cause.name
end
- # TODO: The reason for this test is unclear, improve documentation
- def test_render_partial_and_fallback_to_layout
+ def test_render_partial_with_no_block_given_to_yield
assert_equal "Before (Josh)\n\nAfter", @view.render(partial: "test/layout_for_partial", locals: { name: "Josh" })
end
diff --git a/activejob/CHANGELOG.md b/activejob/CHANGELOG.md
index 5e8d8cb5c9..6f95553ee5 100644
--- a/activejob/CHANGELOG.md
+++ b/activejob/CHANGELOG.md
@@ -1,3 +1,7 @@
+* Push skipped jobs to `enqueued_jobs` when using `perform_enqueued_jobs` with a `only` filter in tests
+
+ *Alexander Pauly*
+
* Removed deprecated support to passing the adapter class to `.queue_adapter`.
*Rafael Mendonça França*
diff --git a/activejob/lib/active_job/queue_adapters/test_adapter.rb b/activejob/lib/active_job/queue_adapters/test_adapter.rb
index da042cfebf..ec825f12cd 100644
--- a/activejob/lib/active_job/queue_adapters/test_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/test_adapter.rb
@@ -24,15 +24,11 @@ module ActiveJob
end
def enqueue(job) #:nodoc:
- return if filtered?(job)
-
job_data = job_to_hash(job)
enqueue_or_perform(perform_enqueued_jobs, job, job_data)
end
def enqueue_at(job, timestamp) #:nodoc:
- return if filtered?(job)
-
job_data = job_to_hash(job, at: timestamp)
enqueue_or_perform(perform_enqueued_at_jobs, job, job_data)
end
@@ -44,11 +40,11 @@ module ActiveJob
end
def enqueue_or_perform(perform, job, job_data)
- if perform
+ if !perform || filtered?(job)
+ enqueued_jobs << job_data
+ else
performed_jobs << job_data
Base.execute job.serialize
- else
- enqueued_jobs << job_data
end
end
diff --git a/activejob/test/cases/test_helper_test.rb b/activejob/test/cases/test_helper_test.rb
index 5488ce3d58..372b68c2f5 100644
--- a/activejob/test/cases/test_helper_test.rb
+++ b/activejob/test/cases/test_helper_test.rb
@@ -56,6 +56,17 @@ class EnqueuedJobsTest < ActiveJob::TestCase
end
end
+ def test_assert_enqueued_jobs_when_performing_with_only_option
+ assert_nothing_raised do
+ assert_enqueued_jobs 1, only: HelloJob do
+ perform_enqueued_jobs only: LoggingJob do
+ HelloJob.perform_later("sean")
+ LoggingJob.perform_later("yves")
+ end
+ end
+ end
+ end
+
def test_assert_no_enqueued_jobs_with_no_block
assert_nothing_raised do
assert_no_enqueued_jobs
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index 250f48fad9..96b8545dfc 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -44,7 +44,6 @@ module ActiveRecord
autoload :Explain
autoload :Inheritance
autoload :Integration
- autoload :LegacyYamlAdapter
autoload :Migration
autoload :Migrator, "active_record/migration"
autoload :ModelSchema
@@ -85,6 +84,8 @@ module ActiveRecord
autoload :AttributeMethods
autoload :AutosaveAssociation
+ autoload :LegacyYamlAdapter
+
autoload :Relation
autoload :AssociationRelation
autoload :NullRelation
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 604904abcc..1183bdf6f4 100644
--- a/activerecord/lib/active_record/associations/has_one_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_through_association.rb
@@ -22,6 +22,10 @@ module ActiveRecord
elsif record
attributes = construct_join_attributes(record)
+ if through_record && through_record.destroyed?
+ through_record = through_proxy.tap(&:reload).target
+ end
+
if through_record
through_record.update(attributes)
elsif owner.new_record?
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index a79eb03acc..87e0847ec1 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -171,7 +171,7 @@ module ActiveRecord
chain = child.reflection.chain
foreign_table = parent.table
foreign_klass = parent.base_klass
- child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain)
+ child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, chain)
end
def make_outer_joins(parent, child)
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
index a5705951f3..f5fcba1236 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
@@ -23,14 +23,11 @@ module ActiveRecord
JoinInformation = Struct.new :joins, :binds
- def join_constraints(foreign_table, foreign_klass, node, join_type, tables, scope_chain, chain)
+ def join_constraints(foreign_table, foreign_klass, node, join_type, tables, chain)
joins = []
binds = []
tables = tables.reverse
- scope_chain_index = 0
- scope_chain = scope_chain.reverse
-
# The chain starts with the target table, but we want to end with it here (makes
# more sense in this context), so we reverse
chain.reverse_each do |reflection|
@@ -44,7 +41,7 @@ module ActiveRecord
constraint = build_constraint(klass, table, key, foreign_table, foreign_key)
predicate_builder = PredicateBuilder.new(TableMetadata.new(klass, table))
- scope_chain_items = scope_chain[scope_chain_index].map do |item|
+ scope_chain_items = reflection.scopes.map do |item|
if item.is_a?(Relation)
item
else
@@ -52,7 +49,6 @@ module ActiveRecord
.instance_exec(node, &item)
end
end
- scope_chain_index += 1
klass_scope =
if klass.current_scope
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 315d70c33f..a2c5ef6817 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -438,7 +438,7 @@ module ActiveRecord
end
end
- def get_oid_type(oid, fmod, column_name, sql_type = "")
+ def get_oid_type(oid, fmod, column_name, sql_type = "".freeze)
if !type_map.key?(oid)
load_additional_types(type_map, [oid])
end
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 2c8c4b6297..81ec4924b0 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -1,5 +1,6 @@
require "thread"
require "active_support/core_ext/string/filters"
+require "active_support/deprecation"
module ActiveRecord
# = Active Record Reflection
@@ -175,8 +176,19 @@ module ActiveRecord
JoinKeys.new(foreign_key, active_record_primary_key)
end
+ # Returns a list of scopes that should be applied for this Reflection
+ # object when querying the database.
+ def scopes
+ scope ? [scope] : []
+ end
+
+ def scope_chain
+ chain.map(&:scopes)
+ end
+ deprecate :scope_chain
+
def constraints
- scope_chain.flatten
+ chain.map(&:scopes).flatten
end
def counter_cache_column
@@ -461,12 +473,6 @@ module ActiveRecord
false
end
- # An array of arrays of scopes. Each item in the outside array corresponds to a reflection
- # in the #chain.
- def scope_chain
- scope ? [[scope]] : [[]]
- end
-
def has_scope?
scope
end
@@ -796,45 +802,12 @@ module ActiveRecord
through_reflection.clear_association_scope_cache
end
- # Consider the following example:
- #
- # class Person
- # has_many :articles
- # has_many :comment_tags, through: :articles
- # end
- #
- # class Article
- # has_many :comments
- # has_many :comment_tags, through: :comments, source: :tags
- # end
- #
- # class Comment
- # has_many :tags
- # end
- #
- # There may be scopes on Person.comment_tags, Article.comment_tags and/or Comment.tags,
- # but only Comment.tags will be represented in the #chain. So this method creates an array
- # of scopes corresponding to the chain.
- def scope_chain
- @scope_chain ||= begin
- scope_chain = source_reflection.scope_chain.map(&:dup)
-
- # Add to it the scope from this reflection (if any)
- scope_chain.first << scope if scope
-
- through_scope_chain = through_reflection.scope_chain.map(&:dup)
-
- if options[:source_type]
- type = foreign_type
- source_type = options[:source_type]
- through_scope_chain.first << lambda { |object|
- where(type => source_type)
- }
- end
+ def scopes
+ source_reflection.scopes + super
+ end
- # Recursively fill out the rest of the array from the through reflection
- scope_chain + through_scope_chain
- end
+ def source_type_scope
+ through_reflection.klass.where(foreign_type => options[:source_type])
end
def has_scope?
@@ -1008,6 +981,15 @@ module ActiveRecord
@previous_reflection = previous_reflection
end
+ def scopes
+ scopes = @previous_reflection.scopes
+ if @previous_reflection.options[:source_type]
+ scopes + [@previous_reflection.source_type_scope]
+ else
+ scopes
+ end
+ end
+
def klass
@reflection.klass
end
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 6663bdb244..4548944fe6 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -17,8 +17,8 @@ module ActiveRecord
# Person.where("administrator = 1").order("created_on DESC").find(1)
#
# NOTE: The returned records may not be in the same order as the ids you
- # provide since database rows are unordered. You'd need to provide an explicit QueryMethods#order
- # option if you want the results are sorted.
+ # provide since database rows are unordered. You will need to provide an explicit QueryMethods#order
+ # option if you want the results to be sorted.
#
# ==== Find with lock
#
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 7d054b874b..11f4aae5b3 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -739,18 +739,25 @@ class EagerAssociationTest < ActiveRecord::TestCase
end
def test_eager_with_invalid_association_reference
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
Post.all.merge!(includes: :monkeys).find(6)
}
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
+ assert_equal("Association named 'monkeys' was not found on Post; perhaps you misspelled it?", e.message)
+
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
Post.all.merge!(includes: [ :monkeys ]).find(6)
}
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
+ assert_equal("Association named 'monkeys' was not found on Post; perhaps you misspelled it?", e.message)
+
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
Post.all.merge!(includes: [ "monkeys" ]).find(6)
}
- assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
+ assert_equal("Association named 'monkeys' was not found on Post; perhaps you misspelled it?", e.message)
+
+ e = assert_raise(ActiveRecord::AssociationNotFoundError) {
Post.all.merge!(includes: [ :monkeys, :elephants ]).find(6)
}
+ assert_equal("Association named 'monkeys' was not found on Post; perhaps you misspelled it?", e.message)
end
def test_eager_has_many_through_with_order
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 432c3526a5..38a729d2d4 100644
--- a/activerecord/test/cases/associations/has_one_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_through_associations_test.rb
@@ -86,6 +86,13 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
assert_nil @member.club
end
+ def test_set_record_after_delete_association
+ @member.club = nil
+ @member.club = clubs(:moustache_club)
+ @member.reload
+ assert_equal clubs(:moustache_club), @member.club
+ end
+
def test_has_one_through_polymorphic
assert_equal clubs(:moustache_club), @member.sponsor_club
end
diff --git a/activerecord/test/cases/migrator_test.rb b/activerecord/test/cases/migrator_test.rb
index 224e8d1854..20d70b75ac 100644
--- a/activerecord/test/cases/migrator_test.rb
+++ b/activerecord/test/cases/migrator_test.rb
@@ -45,10 +45,11 @@ class MigratorTest < ActiveRecord::TestCase
end
def test_migrator_with_duplicate_names
- assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
+ e = assert_raises(ActiveRecord::DuplicateMigrationNameError) do
list = [ActiveRecord::Migration.new("Chunky"), ActiveRecord::Migration.new("Chunky")]
ActiveRecord::Migrator.new(:up, list)
end
+ assert_match(/Multiple migrations have the name Chunky/, e.message)
end
def test_migrator_with_duplicate_versions
diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb
index 2444eccab1..04ee67c177 100644
--- a/activerecord/test/cases/reflection_test.rb
+++ b/activerecord/test/cases/reflection_test.rb
@@ -258,7 +258,9 @@ class ReflectionTest < ActiveRecord::TestCase
[Post.reflect_on_association(:first_taggings).scope],
[Author.reflect_on_association(:misc_posts).scope]
]
- actual = Author.reflect_on_association(:misc_post_first_blue_tags).scope_chain
+ actual = assert_deprecated do
+ Author.reflect_on_association(:misc_post_first_blue_tags).scope_chain
+ end
assert_equal expected, actual
expected = [
@@ -270,7 +272,9 @@ class ReflectionTest < ActiveRecord::TestCase
[],
[]
]
- actual = Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
+ actual = assert_deprecated do
+ Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
+ end
assert_equal expected, actual
end
@@ -395,9 +399,15 @@ class ReflectionTest < ActiveRecord::TestCase
end
def test_through_reflection_scope_chain_does_not_modify_other_reflections
- orig_conds = Post.reflect_on_association(:first_blue_tags_2).scope_chain.inspect
- Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
- assert_equal orig_conds, Post.reflect_on_association(:first_blue_tags_2).scope_chain.inspect
+ orig_conds = assert_deprecated do
+ Post.reflect_on_association(:first_blue_tags_2).scope_chain
+ end.inspect
+ assert_deprecated do
+ Author.reflect_on_association(:misc_post_first_blue_tags_2).scope_chain
+ end
+ assert_equal orig_conds, assert_deprecated {
+ Post.reflect_on_association(:first_blue_tags_2).scope_chain
+ }.inspect
end
def test_symbol_for_class_name
diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb
index ed4604c2df..8e0dc71dca 100644
--- a/activesupport/lib/active_support/evented_file_update_checker.rb
+++ b/activesupport/lib/active_support/evented_file_update_checker.rb
@@ -32,6 +32,10 @@ module ActiveSupport
#
class EventedFileUpdateChecker #:nodoc: all
def initialize(files, dirs = {}, &block)
+ unless block
+ raise ArgumentError, "A block is required to initialize an EventedFileUpdateChecker"
+ end
+
@ph = PathHelper.new
@files = files.map { |f| @ph.xpath(f) }.to_set
diff --git a/activesupport/lib/active_support/file_update_checker.rb b/activesupport/lib/active_support/file_update_checker.rb
index 2dbbfadac1..2b5e3c1350 100644
--- a/activesupport/lib/active_support/file_update_checker.rb
+++ b/activesupport/lib/active_support/file_update_checker.rb
@@ -38,6 +38,10 @@ module ActiveSupport
# changes. The array of files and list of directories cannot be changed
# after FileUpdateChecker has been initialized.
def initialize(files, dirs = {}, &block)
+ unless block
+ raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
+ end
+
@files = files.freeze
@glob = compile_glob(dirs)
@block = block
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index da4e91e949..880340ca86 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -45,7 +45,7 @@ module ActiveSupport
#
# number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
# # => "(755) 6123-4567"
- # number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
+ # number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/)
# # => "133-1234-5678"
def number_to_phone(number, options = {})
NumberToPhoneConverter.convert(number, options)
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index 53a75f0ad4..577675ecdf 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -271,7 +271,8 @@ class DependenciesTest < ActiveSupport::TestCase
def test_raising_discards_autoloaded_constants
with_autoloading_fixtures do
- assert_raises(Exception, "arbitray exception message") { RaisesArbitraryException }
+ e = assert_raises(Exception) { RaisesArbitraryException }
+ assert_equal("arbitray exception message", e.message)
assert_not defined?(A)
assert_not defined?(RaisesArbitraryException)
end
diff --git a/activesupport/test/file_update_checker_shared_tests.rb b/activesupport/test/file_update_checker_shared_tests.rb
index 48cd387196..d038b4debd 100644
--- a/activesupport/test/file_update_checker_shared_tests.rb
+++ b/activesupport/test/file_update_checker_shared_tests.rb
@@ -273,4 +273,10 @@ module FileUpdateCheckerSharedTests
assert checker.execute_if_updated
assert_equal 2, i
end
+
+ test "initialize raises an ArgumentError if no block given" do
+ assert_raise ArgumentError do
+ checker = new_checker([])
+ end
+ end
end
diff --git a/activesupport/test/reloader_test.rb b/activesupport/test/reloader_test.rb
index 67d8c4b0e3..bdd80307c7 100644
--- a/activesupport/test/reloader_test.rb
+++ b/activesupport/test/reloader_test.rb
@@ -2,12 +2,15 @@ require "abstract_unit"
class ReloaderTest < ActiveSupport::TestCase
def test_prepare_callback
- prepared = false
+ prepared = completed = false
reloader.to_prepare { prepared = true }
+ reloader.to_complete { completed = true }
assert !prepared
+ assert !completed
reloader.prepare!
assert prepared
+ assert !completed
prepared = false
reloader.wrap do
@@ -17,6 +20,15 @@ class ReloaderTest < ActiveSupport::TestCase
assert !prepared
end
+ def test_prepend_prepare_callback
+ i = 10
+ reloader.to_prepare { i += 1 }
+ reloader.to_prepare(prepend: true) { i = 0 }
+
+ reloader.prepare!
+ assert_equal 1, i
+ end
+
def test_only_run_when_check_passes
r = new_reloader { true }
invoked = false
diff --git a/activesupport/test/security_utils_test.rb b/activesupport/test/security_utils_test.rb
index 842bdd469d..e8f762da22 100644
--- a/activesupport/test/security_utils_test.rb
+++ b/activesupport/test/security_utils_test.rb
@@ -4,6 +4,11 @@ require "active_support/security_utils"
class SecurityUtilsTest < ActiveSupport::TestCase
def test_secure_compare_should_perform_string_comparison
assert ActiveSupport::SecurityUtils.secure_compare("a", "a")
- assert !ActiveSupport::SecurityUtils.secure_compare("a", "b")
+ assert_not ActiveSupport::SecurityUtils.secure_compare("a", "b")
+ end
+
+ def test_variable_size_secure_compare_should_perform_string_comparison
+ assert ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "a")
+ assert_not ActiveSupport::SecurityUtils.variable_size_secure_compare("a", "b")
end
end
diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb
index cfc6447360..e0d3fb0cf5 100644
--- a/activesupport/test/time_travel_test.rb
+++ b/activesupport/test/time_travel_test.rb
@@ -94,11 +94,12 @@ class TimeTravelTest < ActiveSupport::TestCase
outer_expected_time = Time.new(2004, 11, 24, 01, 04, 44)
inner_expected_time = Time.new(2004, 10, 24, 01, 04, 44)
travel_to outer_expected_time do
- assert_raises(RuntimeError, /Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing./) do
+ e = assert_raises(RuntimeError) do
travel_to(inner_expected_time) do
#noop
end
end
+ assert_match(/Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing./, e.message)
end
end
end
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 4db6e3e195..0b7cc055be 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -409,6 +409,35 @@ NOTE: You need to restart the server when you add new locale files.
You may use YAML (`.yml`) or plain Ruby (`.rb`) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.)
+If your translations are stored in YAML files, certain keys must be escaped. They are:
+
+* true, on, yes
+* false, off, no
+
+Examples:
+
+```erb
+# confing/locales/en.yml
+en:
+ success:
+ 'true': 'True!'
+ 'on': 'On!'
+ 'false': 'False!'
+ failure:
+ true: 'True!'
+ off: 'Off!'
+ false: 'False!'
+```
+
+```ruby
+I18n.t 'success.true' # => 'True!'
+I18n.t 'success.on' # => 'On!'
+I18n.t 'success.false' # => 'False!'
+I18n.t 'failure.false' # => Translation Missing
+I18n.t 'failure.off' # => Translation Missing
+I18n.t 'failure.true' # => Translation Missing
+```
+
### Passing Variables to Translations
One key consideration for successfully internationalizing an application is to
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index a855e8fab0..c027d06663 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -124,6 +124,7 @@ module Rails
# the hook are taken into account.
initializer :set_routes_reloader_hook do |app|
reloader = routes_reloader
+ reloader.eager_load = app.config.eager_load
reloader.execute_if_updated
reloaders << reloader
app.reloader.to_run do
diff --git a/railties/lib/rails/application/routes_reloader.rb b/railties/lib/rails/application/routes_reloader.rb
index cf0a4e128f..e02ef629f2 100644
--- a/railties/lib/rails/application/routes_reloader.rb
+++ b/railties/lib/rails/application/routes_reloader.rb
@@ -4,11 +4,13 @@ module Rails
class Application
class RoutesReloader
attr_reader :route_sets, :paths
- delegate :execute_if_updated, :execute, :updated?, to: :updater
+ attr_accessor :eager_load
+ delegate :updated?, to: :updater
def initialize
@paths = []
@route_sets = []
+ @eager_load = false
end
def reload!
@@ -19,6 +21,19 @@ module Rails
revert
end
+ def execute
+ ret = updater.execute
+ route_sets.each(&:eager_load!) if eager_load
+ ret
+ end
+
+ def execute_if_updated
+ if updated = updater.execute_if_updated
+ route_sets.each(&:eager_load!) if eager_load
+ end
+ updated
+ end
+
private
def updater
diff --git a/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml b/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml
index 0653957166..decc5a8573 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml
+++ b/railties/lib/rails/generators/rails/app/templates/config/locales/en.yml
@@ -16,6 +16,16 @@
#
# This would use the information in config/locales/es.yml.
#
+# The following keys must be escaped otherwise they will not be retrieved by
+# the default I18n backend:
+#
+# true, false, on, off, yes, no
+#
+# Instead, surround them with single quotes.
+#
+# en:
+# 'true': 'foo'
+#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.
diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb
index 01a9807b6b..824831155e 100644
--- a/railties/test/application/configuration_test.rb
+++ b/railties/test/application/configuration_test.rb
@@ -623,9 +623,10 @@ module ApplicationTests
assert_equal "", app.config.secret_token
assert_nil app.secrets.secret_key_base
- assert_raise ArgumentError, /\AA secret is required/ do
+ e = assert_raise ArgumentError do
app.key_generator
end
+ assert_match(/\AA secret is required/, e.message)
end
test "that nested keys are symbolized the same as parents for hashes more than one level deep" do
@@ -1184,11 +1185,12 @@ module ApplicationTests
end
test "config.session_store with :active_record_store without activerecord-session_store gem" do
- assert_raise RuntimeError, /activerecord-session_store/ do
+ e = assert_raise RuntimeError do
make_basic_app do |application|
application.config.session_store :active_record_store
end
end
+ assert_match(/activerecord-session_store/, e.message)
end
test "default session store initializer does not overwrite the user defined session store even if it is disabled" do
diff --git a/railties/test/application/mailer_previews_test.rb b/railties/test/application/mailer_previews_test.rb
index 790aca2aa4..c3a360e5d4 100644
--- a/railties/test/application/mailer_previews_test.rb
+++ b/railties/test/application/mailer_previews_test.rb
@@ -671,6 +671,40 @@ module ApplicationTests
assert_match %r[<p>Hello, World!</p>], last_response.body
end
+ test "multipart mailer preview with empty parts" do
+ mailer "notifier", <<-RUBY
+ class Notifier < ActionMailer::Base
+ default from: "from@example.com"
+
+ def foo
+ mail to: "to@example.org"
+ end
+ end
+ RUBY
+
+ text_template "notifier/foo", <<-RUBY
+ RUBY
+
+ html_template "notifier/foo", <<-RUBY
+ RUBY
+
+ mailer_preview "notifier", <<-RUBY
+ class NotifierPreview < ActionMailer::Preview
+ def foo
+ Notifier.foo
+ end
+ end
+ RUBY
+
+ app("development")
+
+ get "/rails/mailers/notifier/foo?part=text/plain"
+ assert_equal 200, last_response.status
+
+ get "/rails/mailers/notifier/foo?part=text/html"
+ assert_equal 200, last_response.status
+ end
+
private
def build_app
super