diff options
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/CHANGELOG.md | 28 | ||||
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 42 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/inclusion.rb | 4 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/try.rb | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/testing/assertions.rb | 4 | ||||
-rw-r--r-- | activesupport/test/callbacks_test.rb | 20 | ||||
-rw-r--r-- | activesupport/test/test_case_test.rb | 8 |
7 files changed, 68 insertions, 40 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 69413fef47..a39344e464 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,14 @@ +* `assert_difference` and `assert_no_difference` now returns the result of the + yielded block. + + Example: + + post = assert_difference -> { Post.count }, 1 do + Post.create + end + + *Lucas Mazza* + * Short-circuit `blank?` on date and time values since they are never blank. Fixes #21657 @@ -12,7 +23,7 @@ * Updated Unicode version to 8.0.0 *Anshul Sharma* - + * `number_to_currency` and `number_with_delimiter` now accept custom `delimiter_pattern` option to handle placement of delimiter, to support currency formats like INR @@ -277,20 +288,17 @@ The preferred method to halt a callback chain from now on is to explicitly `throw(:abort)`. - In the past, returning `false` in an ActiveSupport callback had the side - effect of halting the callback chain. This is not recommended anymore and, - depending on the value of - `Callbacks::CallbackChain.halt_and_display_warning_on_return_false`, will - either not work at all or display a deprecation warning. + In the past, callbacks could only be halted by explicitly providing a + terminator and by having a callback match the conditions of the terminator. * Add `Callbacks::CallbackChain.halt_and_display_warning_on_return_false` Setting `Callbacks::CallbackChain.halt_and_display_warning_on_return_false` - to `true` will let an app support the deprecated way of halting callback - chains by returning `false`. + to `true` will let an app support the deprecated way of halting Active Record, + Active Model and Active Model validations callback chains by returning `false`. Setting the value to `false` will tell the app to ignore any `false` value - returned by callbacks, and only halt the chain upon `throw(:abort)`. + returned by those callbacks, and only halt the chain upon `throw(:abort)`. The value can also be set with the Rails configuration option `config.active_support.halt_callback_chains_on_return_false`. @@ -300,7 +308,7 @@ For new Rails 5.0 apps, its value is set to `false` in an initializer, so these apps will support the new behavior by default. - *claudiob* + *claudiob*, *Roque Pinel* * Changes arguments and default value of CallbackChain's `:terminator` option diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 80c5fdba17..3db9ea2ac0 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -536,23 +536,12 @@ module ActiveSupport Proc.new do |target, result_lambda| terminate = true catch(:abort) do - result = result_lambda.call if result_lambda.is_a?(Proc) - if halt_and_display_warning_on_return_false && result == false - display_deprecation_warning_for_false_terminator - else - terminate = false - end + result_lambda.call if result_lambda.is_a?(Proc) + terminate = false end terminate end end - - def display_deprecation_warning_for_false_terminator - ActiveSupport::Deprecation.warn(<<-MSG.squish) - Returning `false` in a callback will not implicitly halt a callback chain in the next release of Rails. - To explicitly halt a callback chain, please use `throw :abort` instead. - MSG - end end module ClassMethods @@ -686,7 +675,8 @@ module ActiveSupport # # In this example, if any before validate callbacks returns +false+, # any successive before and around callback is not executed. - # Defaults to +false+, meaning no value halts the chain. + # + # The default terminator halts the chain when a callback throws +:abort+. # # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after # callbacks should be terminated by the <tt>:terminator</tt> option. By @@ -764,6 +754,30 @@ module ActiveSupport def set_callbacks(name, callbacks) send "_#{name}_callbacks=", callbacks end + + def deprecated_false_terminator + Proc.new do |target, result_lambda| + terminate = true + catch(:abort) do + result = result_lambda.call if result_lambda.is_a?(Proc) + if CallbackChain.halt_and_display_warning_on_return_false && result == false + display_deprecation_warning_for_false_terminator + else + terminate = false + end + end + terminate + end + end + + private + + def display_deprecation_warning_for_false_terminator + ActiveSupport::Deprecation.warn(<<-MSG.squish) + Returning `false` in Active Record and Active Model callbacks will not implicitly halt a callback chain in the next release of Rails. + To explicitly halt the callback chain, please use `throw :abort` instead. + MSG + end end end end diff --git a/activesupport/lib/active_support/core_ext/object/inclusion.rb b/activesupport/lib/active_support/core_ext/object/inclusion.rb index 55f281b213..d4c17dfb07 100644 --- a/activesupport/lib/active_support/core_ext/object/inclusion.rb +++ b/activesupport/lib/active_support/core_ext/object/inclusion.rb @@ -5,7 +5,7 @@ class Object # characters = ["Konata", "Kagami", "Tsukasa"] # "Konata".in?(characters) # => true # - # This will throw an ArgumentError if the argument doesn't respond + # This will throw an +ArgumentError+ if the argument doesn't respond # to +#include?+. def in?(another_object) another_object.include?(self) @@ -18,7 +18,7 @@ class Object # # params[:bucket_type].presence_in %w( project calendar ) # - # This will throw an ArgumentError if the argument doesn't respond to +#include?+. + # This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+. # # @return [Object] def presence_in(another_object) diff --git a/activesupport/lib/active_support/core_ext/object/try.rb b/activesupport/lib/active_support/core_ext/object/try.rb index c67eb25b68..8c16d95b62 100644 --- a/activesupport/lib/active_support/core_ext/object/try.rb +++ b/activesupport/lib/active_support/core_ext/object/try.rb @@ -94,7 +94,7 @@ class Object # :call-seq: # try!(*a, &b) # - # Same as #try, but raises a NoMethodError exception if the receiver is + # Same as #try, but raises a +NoMethodError+ exception if the receiver is # not +nil+ and does not implement the tried method. # # "a".try!(:upcase) # => "A" diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb index d87ce3474d..ae8c15d8bf 100644 --- a/activesupport/lib/active_support/testing/assertions.rb +++ b/activesupport/lib/active_support/testing/assertions.rb @@ -68,13 +68,15 @@ module ActiveSupport } before = exps.map(&:call) - yield + retval = yield expressions.zip(exps).each_with_index do |(code, e), i| error = "#{code.inspect} didn't change by #{difference}" error = "#{message}.\n#{error}" if message assert_equal(before[i] + difference, e.call, error) end + + retval end # Assertion that the numeric result of evaluating an expression is not diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index cda9732cae..4f47e0519f 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -766,13 +766,11 @@ module CallbacksTest end class CallbackFalseTerminatorWithoutConfigTest < ActiveSupport::TestCase - def test_returning_false_halts_callback_if_config_variable_is_not_set + def test_returning_false_does_not_halt_callback_if_config_variable_is_not_set obj = CallbackFalseTerminator.new - assert_deprecated do - obj.save - assert_equal :second, obj.halted - assert !obj.saved - end + obj.save + assert_equal nil, obj.halted + assert obj.saved end end @@ -781,13 +779,11 @@ module CallbacksTest ActiveSupport::Callbacks::CallbackChain.halt_and_display_warning_on_return_false = true end - def test_returning_false_halts_callback_if_config_variable_is_true + def test_returning_false_does_not_halt_callback_if_config_variable_is_true obj = CallbackFalseTerminator.new - assert_deprecated do - obj.save - assert_equal :second, obj.halted - assert !obj.saved - end + obj.save + assert_equal nil, obj.halted + assert obj.saved end end diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index 9e6d1a91d0..18228a2ac5 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -56,6 +56,14 @@ class AssertDifferenceTest < ActiveSupport::TestCase end end + def test_assert_difference_retval + incremented = assert_difference '@object.num', +1 do + @object.increment + end + + assert_equal incremented, 1 + end + def test_assert_difference_with_implicit_difference assert_difference '@object.num' do @object.increment |