aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md65
-rw-r--r--activesupport/lib/active_support/core_ext/array/conversions.rb10
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb1
-rw-r--r--activesupport/lib/active_support/duration/iso8601_serializer.rb4
-rw-r--r--activesupport/lib/active_support/lazy_load_hooks.rb44
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb89
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb1
-rw-r--r--activesupport/test/caching_test.rb22
-rw-r--r--activesupport/test/core_ext/array/conversions_test.rb7
-rw-r--r--activesupport/test/core_ext/duration_test.rb1
-rw-r--r--activesupport/test/load_paths_test.rb16
-rw-r--r--activesupport/test/test_case_test.rb106
-rw-r--r--activesupport/test/time_travel_test.rb70
-rw-r--r--activesupport/test/time_zone_test.rb7
15 files changed, 368 insertions, 77 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 1c6f340fba..3749dda9fc 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,13 +1,61 @@
+* Introduce `assert_changes` and `assert_no_changes`.
+
+ `assert_changes` is a more general `assert_difference` that works with any
+ value.
+
+ assert_changes 'Error.current', from: nil, to: 'ERR' do
+ expected_bad_operation
+ end
+
+ Can be called with strings, to be evaluated in the binding (context) of
+ the block given to the assertion, or a lambda.
+
+ assert_changes -> { Error.current }, from: nil, to: 'ERR' do
+ expected_bad_operation
+ end
+
+ The `from` and `to` arguments are compared with the case operator (`===`).
+
+ assert_changes 'Error.current', from: nil, to: Error do
+ expected_bad_operation
+ end
+
+ This is pretty useful, if you need to loosely compare a value. For example,
+ you need to test a token has been generated and it has that many random
+ characters.
+
+ user = User.start_registration
+ assert_changes 'user.token', to: /\w{32}/ do
+ user.finish_registration
+ end
+
+ *Genadi Samokovarov*
+
+* Add `:fallback_string` option to `Array#to_sentence`. If an empty array
+ calls the function and a fallback string option is set then it returns the
+ fallback string other than an empty string.
+
+ *Mohamed Osama*
+
+* Fix `ActiveSupport::TimeZone#strptime`. Now raises `ArgumentError` when the
+ given time doesn't match the format. The error is the same as the one given
+ by Ruby's `Date.strptime`. Previously it raised
+ `NoMethodError: undefined method empty? for nil:NilClass.` due to a bug.
+
+ Fixes #25701.
+
+ *John Gesimondo*
+
* `travel/travel_to` travel time helpers, now raise on nested calls,
as this can lead to confusing time stubbing.
-
+
Instead of:
-
+
travel_to 2.days.from_now do
# 2 days from today
travel_to 3.days.from_now do
# 5 days from today
- end
+ end
end
preferred way to achieve above is:
@@ -15,13 +63,12 @@
travel 2.days do
# 2 days from today
end
-
- travel 5.days do
- # 5 days from today
- end
-
+
+ travel 5.days do
+ # 5 days from today
+ end
+
*Vipul A M*
-
* Support parsing JSON time in ISO8601 local time strings in
`ActiveSupport::JSON.decode` when `parse_json_times` is enabled.
diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb
index 8718b7e1e5..54fb83581a 100644
--- a/activesupport/lib/active_support/core_ext/array/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/array/conversions.rb
@@ -40,6 +40,12 @@ class Array
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
# # => "one or two or at least three"
#
+ # [].to_sentence(fallback_string: 'none')
+ # # => "none"
+ #
+ # ['one', 'two'].to_sentence(fallback_string: 'none')
+ # # => "one and two"
+ #
# Using <tt>:locale</tt> option:
#
# # Given this locale dictionary:
@@ -57,7 +63,7 @@ class Array
# ['uno', 'dos', 'tres'].to_sentence(locale: :es)
# # => "uno o dos o al menos tres"
def to_sentence(options = {})
- options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
+ options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale, :fallback_string)
default_connectors = {
:words_connector => ', ',
@@ -72,7 +78,7 @@ class Array
case length
when 0
- ''
+ "#{options[:fallback_string] || ''}"
when 1
"#{self[0]}"
when 2
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 802d988af2..aa0e2a1a88 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -27,7 +27,7 @@ class Class
# This matches normal Ruby method inheritance: think of writing an attribute
# on a subclass as overriding the reader method. However, you need to be aware
# when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
- # In such cases, you don't want to do changes in places but use setters:
+ # In such cases, you don't want to do changes in place. Instead use setters:
#
# Base.setting = []
# Base.setting # => []
diff --git a/activesupport/lib/active_support/core_ext/string/output_safety.rb b/activesupport/lib/active_support/core_ext/string/output_safety.rb
index 005ad93b08..f1a0c47c54 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -1,5 +1,6 @@
require 'erb'
require 'active_support/core_ext/kernel/singleton_class'
+require 'active_support/multibyte/unicode'
class ERB
module Util
diff --git a/activesupport/lib/active_support/duration/iso8601_serializer.rb b/activesupport/lib/active_support/duration/iso8601_serializer.rb
index 05c6a083a9..eb8136e208 100644
--- a/activesupport/lib/active_support/duration/iso8601_serializer.rb
+++ b/activesupport/lib/active_support/duration/iso8601_serializer.rb
@@ -12,8 +12,10 @@ module ActiveSupport
# Builds and returns output string.
def serialize
- output = 'P'
parts, sign = normalize
+ return "PT0S".freeze if parts.empty?
+
+ output = 'P'
output << "#{parts[:years]}Y" if parts.key?(:years)
output << "#{parts[:months]}M" if parts.key?(:months)
output << "#{parts[:weeks]}W" if parts.key?(:weeks)
diff --git a/activesupport/lib/active_support/lazy_load_hooks.rb b/activesupport/lib/active_support/lazy_load_hooks.rb
index e2b8f0f648..67b54b45ea 100644
--- a/activesupport/lib/active_support/lazy_load_hooks.rb
+++ b/activesupport/lib/active_support/lazy_load_hooks.rb
@@ -20,29 +20,37 @@ module ActiveSupport
# +activerecord/lib/active_record/base.rb+ is:
#
# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
- @load_hooks = Hash.new { |h,k| h[k] = [] }
- @loaded = Hash.new { |h,k| h[k] = [] }
-
- def self.on_load(name, options = {}, &block)
- @loaded[name].each do |base|
- execute_hook(base, options, block)
+ module LazyLoadHooks
+ def self.extended(base) # :nodoc:
+ base.class_eval do
+ @load_hooks = Hash.new { |h,k| h[k] = [] }
+ @loaded = Hash.new { |h,k| h[k] = [] }
+ end
end
- @load_hooks[name] << [block, options]
- end
+ def on_load(name, options = {}, &block)
+ @loaded[name].each do |base|
+ execute_hook(base, options, block)
+ end
- def self.execute_hook(base, options, block)
- if options[:yield]
- block.call(base)
- else
- base.instance_eval(&block)
+ @load_hooks[name] << [block, options]
end
- end
- def self.run_load_hooks(name, base = Object)
- @loaded[name] << base
- @load_hooks[name].each do |hook, options|
- execute_hook(base, options, hook)
+ def execute_hook(base, options, block)
+ if options[:yield]
+ block.call(base)
+ else
+ base.instance_eval(&block)
+ end
+ end
+
+ def run_load_hooks(name, base = Object)
+ @loaded[name] << base
+ @load_hooks[name].each do |hook, options|
+ execute_hook(base, options, hook)
+ end
end
end
+
+ extend LazyLoadHooks
end
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index ad83638572..7770aa8006 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -1,6 +1,8 @@
module ActiveSupport
module Testing
module Assertions
+ UNTRACKED = Object.new # :nodoc:
+
# Asserts that an expression is not truthy. Passes if <tt>object</tt> is
# +nil+ or +false+. "Truthy" means "considered true in a conditional"
# like <tt>if foo</tt>.
@@ -92,6 +94,93 @@ module ActiveSupport
def assert_no_difference(expression, message = nil, &block)
assert_difference expression, 0, message, &block
end
+
+ # Assertion that the result of evaluating an expression is changed before
+ # and after invoking the passed in block.
+ #
+ # assert_changes 'Status.all_good?' do
+ # post :create, params: { status: { ok: false } }
+ # end
+ #
+ # You can pass the block as a string to be evaluated in the context of
+ # the block. A lambda can be passed for the block as well.
+ #
+ # assert_changes -> { Status.all_good? } do
+ # post :create, params: { status: { ok: false } }
+ # end
+ #
+ # The assertion is useful to test side effects. The passed block can be
+ # anything that can be converted to string with #to_s.
+ #
+ # assert_changes :@object do
+ # @object = 42
+ # end
+ #
+ # The keyword arguments :from and :to can be given to specify the
+ # expected initial value and the expected value after the block was
+ # executed.
+ #
+ # assert_changes :@object, from: nil, to: :foo do
+ # @object = :foo
+ # end
+ #
+ # An error message can be specified.
+ #
+ # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do
+ # post :create, params: { status: { incident: true } }
+ # end
+ def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block)
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
+
+ before = exp.call
+ retval = yield
+
+ unless from == UNTRACKED
+ error = "#{expression.inspect} isn't #{from}"
+ error = "#{message}.\n#{error}" if message
+ assert from === before, error
+ end
+
+ after = exp.call
+
+ if to == UNTRACKED
+ error = "#{expression.inspect} didn't changed"
+ error = "#{message}.\n#{error}" if message
+ assert_not_equal before, after, error
+ else
+ message = "#{expression.inspect} didn't change to #{to}"
+ error = "#{message}.\n#{error}" if message
+ assert to === after, error
+ end
+
+ retval
+ end
+
+ # Assertion that the result of evaluating an expression is changed before
+ # and after invoking the passed in block.
+ #
+ # assert_no_changes 'Status.all_good?' do
+ # post :create, params: { status: { ok: true } }
+ # end
+ #
+ # An error message can be specified.
+ #
+ # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do
+ # post :create, params: { status: { ok: false } }
+ # end
+ def assert_no_changes(expression, message = nil, &block)
+ exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
+
+ before = exp.call
+ retval = yield
+ after = exp.call
+
+ error = "#{expression.inspect} did change to #{after}"
+ error = "#{message}.\n#{error}" if message
+ assert_equal before, after, error
+
+ retval
+ end
end
end
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 19420cee5e..eb89a6d4c5 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -447,6 +447,7 @@ module ActiveSupport
private
def parts_to_time(parts, now)
+ raise ArgumentError, "invalid date" if parts.nil?
return if parts.empty?
time = Time.new(
diff --git a/activesupport/test/caching_test.rb b/activesupport/test/caching_test.rb
index 8002c14539..d4dec81b28 100644
--- a/activesupport/test/caching_test.rb
+++ b/activesupport/test/caching_test.rb
@@ -25,6 +25,18 @@ module ActiveSupport
assert_nil LocalCacheRegistry.cache_for(key)
end
+ def test_local_cache_cleared_and_response_should_be_present_on_invalid_parameters_error
+ key = "super awesome key"
+ assert_nil LocalCacheRegistry.cache_for key
+ middleware = Middleware.new('<3', key).new(->(env) {
+ assert LocalCacheRegistry.cache_for(key), 'should have a cache'
+ raise Rack::Utils::InvalidParameterError
+ })
+ response = middleware.call({})
+ assert response, 'response should exist'
+ assert_nil LocalCacheRegistry.cache_for(key)
+ end
+
def test_local_cache_cleared_on_exception
key = "super awesome key"
assert_nil LocalCacheRegistry.cache_for key
@@ -128,6 +140,16 @@ class CacheKeyTest < ActiveSupport::TestCase
end
class CacheStoreSettingTest < ActiveSupport::TestCase
+ def test_memory_store_gets_created_if_no_arguments_passed_to_lookup_store_method
+ store = ActiveSupport::Cache.lookup_store
+ assert_kind_of(ActiveSupport::Cache::MemoryStore, store)
+ end
+
+ def test_memory_store
+ store = ActiveSupport::Cache.lookup_store :memory_store
+ assert_kind_of(ActiveSupport::Cache::MemoryStore, store)
+ end
+
def test_file_fragment_cache_store
store = ActiveSupport::Cache.lookup_store :file_store, "/path/to/cache/directory"
assert_kind_of(ActiveSupport::Cache::FileStore, store)
diff --git a/activesupport/test/core_ext/array/conversions_test.rb b/activesupport/test/core_ext/array/conversions_test.rb
index de36e2026d..323b451e02 100644
--- a/activesupport/test/core_ext/array/conversions_test.rb
+++ b/activesupport/test/core_ext/array/conversions_test.rb
@@ -25,6 +25,11 @@ class ToSentenceTest < ActiveSupport::TestCase
assert_equal "one, two and three", ['one', 'two', 'three'].to_sentence(last_word_connector: ' and ')
end
+ def test_to_sentence_with_fallback_string
+ assert_equal "none", [].to_sentence(fallback_string: 'none')
+ assert_equal "one, two, and three", ['one', 'two', 'three'].to_sentence(fallback_string: 'none')
+ end
+
def test_two_elements
assert_equal "one and two", ['one', 'two'].to_sentence
assert_equal "one two", ['one', 'two'].to_sentence(two_words_connector: ' ')
@@ -58,7 +63,7 @@ class ToSentenceTest < ActiveSupport::TestCase
['one', 'two'].to_sentence(passing: 'invalid option')
end
- assert_equal exception.message, "Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale"
+ assert_equal exception.message, "Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale, :fallback_string"
end
def test_always_returns_string
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index 502e2811fa..a24915dfef 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -279,6 +279,7 @@ class DurationTest < ActiveSupport::TestCase
['PT1S', 1.second ],
['PT1.4S', (1.4).seconds ],
['P1Y1M1DT1H', 1.year + 1.month + 1.day + 1.hour],
+ ['PT0S', 0.minutes ],
]
expectations.each do |expected_output, duration|
assert_equal expected_output, duration.iso8601, expected_output.inspect
diff --git a/activesupport/test/load_paths_test.rb b/activesupport/test/load_paths_test.rb
deleted file mode 100644
index ac617a9fd8..0000000000
--- a/activesupport/test/load_paths_test.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'abstract_unit'
-
-class LoadPathsTest < ActiveSupport::TestCase
- def test_uniq_load_paths
- load_paths_count = $LOAD_PATH.inject({}) { |paths, path|
- expanded_path = File.expand_path(path)
- paths[expanded_path] ||= 0
- paths[expanded_path] += 1
- paths
- }
- load_paths_count[File.expand_path('../../lib', __FILE__)] -= 1
-
- load_paths_count.select! { |k, v| v > 1 }
- assert load_paths_count.empty?, load_paths_count.inspect
- end
-end
diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb
index 18228a2ac5..772c3cfca7 100644
--- a/activesupport/test/test_case_test.rb
+++ b/activesupport/test/test_case_test.rb
@@ -111,6 +111,112 @@ class AssertDifferenceTest < ActiveSupport::TestCase
end
end
end
+
+ def test_assert_changes_pass
+ assert_changes '@object.num' do
+ @object.increment
+ end
+ end
+
+ def test_assert_changes_pass_with_lambda
+ assert_changes -> { @object.num } do
+ @object.increment
+ end
+ end
+
+ def test_assert_changes_with_from_option
+ assert_changes '@object.num', from: 0 do
+ @object.increment
+ end
+ end
+
+ def test_assert_changes_with_from_option_with_wrong_value
+ assert_raises Minitest::Assertion do
+ assert_changes '@object.num', from: -1 do
+ @object.increment
+ end
+ end
+ end
+
+ def test_assert_changes_with_to_option
+ assert_changes '@object.num', to: 1 do
+ @object.increment
+ end
+ end
+
+ def test_assert_changes_with_wrong_to_option
+ assert_raises Minitest::Assertion do
+ assert_changes '@object.num', to: 2 do
+ @object.increment
+ end
+ end
+ end
+
+ def test_assert_changes_with_from_option_and_to_option
+ assert_changes '@object.num', from: 0, to: 1 do
+ @object.increment
+ end
+ end
+
+ def test_assert_changes_with_from_and_to_options_and_wrong_to_value
+ assert_raises Minitest::Assertion do
+ assert_changes '@object.num', from: 0, to: 2 do
+ @object.increment
+ end
+ end
+ end
+
+ def test_assert_changes_works_with_any_object
+ retval = silence_warnings do
+ assert_changes :@new_object, from: nil, to: 42 do
+ @new_object = 42
+ end
+ end
+
+ assert_equal 42, retval
+ end
+
+ def test_assert_changes_works_with_nil
+ oldval = @object
+
+ retval = assert_changes :@object, from: oldval, to: nil do
+ @object = nil
+ end
+
+ assert_nil retval
+ end
+
+ def test_assert_changes_with_to_and_case_operator
+ token = nil
+
+ assert_changes 'token', to: /\w{32}/ do
+ token = SecureRandom.hex
+ end
+ end
+
+ def test_assert_changes_with_to_and_from_and_case_operator
+ token = SecureRandom.hex
+
+ assert_changes 'token', from: /\w{32}/, to: /\w{32}/ do
+ token = SecureRandom.hex
+ end
+ end
+
+ def test_assert_no_changes_pass
+ assert_no_changes '@object.num' do
+ # ...
+ end
+ end
+
+ def test_assert_no_changes_with_message
+ error = assert_raises Minitest::Assertion do
+ assert_no_changes '@object.num', '@object.num should not change' do
+ @object.increment
+ end
+ end
+
+ assert_equal "@object.num should not change.\n\"@object.num\" did change to 1.\nExpected: 0\n Actual: 1", error.message
+ end
end
class AlsoDoingNothingTest < ActiveSupport::TestCase
diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb
index e9f87bdf82..e75237e5a4 100644
--- a/activesupport/test/time_travel_test.rb
+++ b/activesupport/test/time_travel_test.rb
@@ -3,18 +3,18 @@ require 'active_support/core_ext/date_time'
require 'active_support/core_ext/numeric/time'
class TimeTravelTest < ActiveSupport::TestCase
- teardown do
- travel_back
- end
-
def test_time_helper_travel
Time.stub(:now, Time.now) do
- expected_time = Time.now + 1.day
- travel 1.day
+ begin
+ expected_time = Time.now + 1.day
+ travel 1.day
- assert_equal expected_time.to_s(:db), Time.now.to_s(:db)
- assert_equal expected_time.to_date, Date.today
- assert_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
+ assert_equal expected_time.to_s(:db), Time.now.to_s(:db)
+ assert_equal expected_time.to_date, Date.today
+ assert_equal expected_time.to_datetime.to_s(:db), DateTime.now.to_s(:db)
+ ensure
+ travel_back
+ end
end
end
@@ -36,12 +36,16 @@ class TimeTravelTest < ActiveSupport::TestCase
def test_time_helper_travel_to
Time.stub(:now, Time.now) do
- expected_time = Time.new(2004, 11, 24, 01, 04, 44)
- travel_to expected_time
+ begin
+ expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ travel_to expected_time
- assert_equal expected_time, Time.now
- assert_equal Date.new(2004, 11, 24), Date.today
- assert_equal expected_time.to_datetime, DateTime.now
+ assert_equal expected_time, Time.now
+ assert_equal Date.new(2004, 11, 24), Date.today
+ assert_equal expected_time.to_datetime, DateTime.now
+ ensure
+ travel_back
+ end
end
end
@@ -63,17 +67,21 @@ class TimeTravelTest < ActiveSupport::TestCase
def test_time_helper_travel_back
Time.stub(:now, Time.now) do
- expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ begin
+ expected_time = Time.new(2004, 11, 24, 01, 04, 44)
- travel_to expected_time
- assert_equal expected_time, Time.now
- assert_equal Date.new(2004, 11, 24), Date.today
- assert_equal expected_time.to_datetime, DateTime.now
- travel_back
+ travel_to expected_time
+ assert_equal expected_time, Time.now
+ assert_equal Date.new(2004, 11, 24), Date.today
+ assert_equal expected_time.to_datetime, DateTime.now
+ travel_back
- assert_not_equal expected_time, Time.now
- assert_not_equal Date.new(2004, 11, 24), Date.today
- assert_not_equal expected_time.to_datetime, DateTime.now
+ assert_not_equal expected_time, Time.now
+ assert_not_equal Date.new(2004, 11, 24), Date.today
+ assert_not_equal expected_time.to_datetime, DateTime.now
+ ensure
+ travel_back
+ end
end
end
@@ -107,14 +115,18 @@ class TimeTravelTest < ActiveSupport::TestCase
def test_time_helper_travel_to_with_subsequent_calls
Time.stub(:now, Time.now) do
- initial_expected_time = Time.new(2004, 11, 24, 01, 04, 44)
- subsequent_expected_time = Time.new(2004, 10, 24, 01, 04, 44)
- assert_nothing_raised do
- travel_to initial_expected_time
- travel_to subsequent_expected_time
+ begin
+ initial_expected_time = Time.new(2004, 11, 24, 01, 04, 44)
+ subsequent_expected_time = Time.new(2004, 10, 24, 01, 04, 44)
+ assert_nothing_raised do
+ travel_to initial_expected_time
+ travel_to subsequent_expected_time
- assert_equal subsequent_expected_time, Time.now
+ assert_equal subsequent_expected_time, Time.now
+ travel_back
+ end
+ ensure
travel_back
end
end
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index a15d5c6a0e..76cbb5ce8b 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -388,6 +388,13 @@ class TimeZoneTest < ActiveSupport::TestCase
end
end
+ def test_strptime_with_malformed_string
+ with_env_tz 'US/Eastern' do
+ zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
+ assert_raise(ArgumentError) { zone.strptime('1999-12-31', '%Y/%m/%d') }
+ end
+ end
+
def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize
tzinfo = TZInfo::Timezone.get('America/New_York')
zone = ActiveSupport::TimeZone.create(tzinfo.name, nil, tzinfo)