aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md11
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb7
-rw-r--r--activesupport/lib/active_support/core_ext/object/blank.rb10
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb14
-rw-r--r--activesupport/test/file_update_checker_shared_tests.rb12
-rw-r--r--activesupport/test/time_zone_test.rb5
6 files changed, 45 insertions, 14 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 21dd0657aa..f8423c3ef8 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,14 @@
+* `ActiveSupport::TimeZone.country_zones(country_code)` looks up the
+ country's time zones by its two-letter ISO3166 country code, e.g.
+
+ >> ActiveSupport::TimeZone.country_zones(:jp).map(&:to_s)
+ => ["(GMT+09:00) Osaka"]
+
+ >> ActiveSupport::TimeZone.country_zones(:uy).map(&:to_s)
+ => ["(GMT-03:00) Montevideo"]
+
+ *Andrey Novikov*
+
* `Array#sum` compat with Ruby 2.4's native method.
Ruby 2.4 introduces `Array#sum`, but it only supports numeric elements,
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 0d46248582..24450cd221 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -149,14 +149,11 @@ class Module
#
# The target method must be public, otherwise it will raise +NoMethodError+.
#
- def delegate(*methods)
- options = methods.pop
- unless options.is_a?(Hash) && to = options[:to]
+ def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
+ unless to
raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
end
- prefix, allow_nil = options.values_at(:prefix, :allow_nil)
-
if prefix == true && to =~ /^[^a-z_]/
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
end
diff --git a/activesupport/lib/active_support/core_ext/object/blank.rb b/activesupport/lib/active_support/core_ext/object/blank.rb
index 039c50a4a2..b08321aeeb 100644
--- a/activesupport/lib/active_support/core_ext/object/blank.rb
+++ b/activesupport/lib/active_support/core_ext/object/blank.rb
@@ -97,8 +97,6 @@ class Hash
end
class String
- BLANK_RE = /\A[[:space:]]*\z/
-
# A string is blank if it's empty or contains whitespaces only:
#
# ''.blank? # => true
@@ -112,7 +110,13 @@ class String
#
# @return [true, false]
def blank?
- BLANK_RE === self
+ # In practice, the majority of blank strings are empty. The predicate is
+ # about 3.5x faster than the regexp check so we first test empty?, and then
+ # fallback. Penalty for the rest of strings is marginal.
+ #
+ # Double negation in the second operand is also a performance tweak, it is
+ # faster than the positive \A[[:space:]]*\z.
+ empty? || !(/[[:^space:]]/ === self)
end
end
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 118bf8eab0..00fdb22c31 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -184,6 +184,7 @@ module ActiveSupport
UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(':', '')
@lazy_zones_map = Concurrent::Map.new
+ @country_zones = Concurrent::Map.new
class << self
# Assumes self represents an offset from UTC in seconds (as returned from
@@ -242,7 +243,18 @@ module ActiveSupport
# A convenience method for returning a collection of TimeZone objects
# for time zones in the USA.
def us_zones
- @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
+ country_zones(:us)
+ end
+
+ # A convenience method for returning a collection of TimeZone objects
+ # for time zones in the country specified by its ISO 3166-1 Alpha2 code.
+ def country_zones(country_code)
+ code = country_code.to_s.upcase
+ @country_zones[code] ||=
+ TZInfo::Country.get(code).zone_identifiers.map do |tz_id|
+ name = MAPPING.key(tz_id)
+ name && self[name]
+ end.compact.sort!
end
private
diff --git a/activesupport/test/file_update_checker_shared_tests.rb b/activesupport/test/file_update_checker_shared_tests.rb
index 12e67a1e9f..40ae0c7617 100644
--- a/activesupport/test/file_update_checker_shared_tests.rb
+++ b/activesupport/test/file_update_checker_shared_tests.rb
@@ -9,7 +9,7 @@ module FileUpdateCheckerSharedTests
end
def tmpfile(name)
- "#{tmpdir}/#{name}"
+ File.join(tmpdir, name)
end
def tmpfiles
@@ -17,7 +17,9 @@ module FileUpdateCheckerSharedTests
end
def run(*args)
- Dir.mktmpdir(nil, __dir__) { |dir| @tmpdir = dir; super }
+ capture_exceptions do
+ Dir.mktmpdir(nil, __dir__) { |dir| @tmpdir = dir; super }
+ end
end
test 'should not execute the block if no paths are given' do
@@ -225,7 +227,7 @@ module FileUpdateCheckerSharedTests
assert !checker.execute_if_updated
assert_equal 0, i
- touch("#{subdir}/nested.rb")
+ touch(File.join(subdir, "nested.rb"))
assert checker.execute_if_updated
assert_equal 1, i
@@ -245,12 +247,12 @@ module FileUpdateCheckerSharedTests
assert_equal 0, i
# subdir does not look for Ruby files, but its parent tmpdir does.
- touch("#{subdir}/nested.rb")
+ touch(File.join(subdir, "nested.rb"))
assert checker.execute_if_updated
assert_equal 1, i
- touch("#{subdir}/nested.txt")
+ touch(File.join(subdir, "nested.txt"))
assert checker.execute_if_updated
assert_equal 2, i
diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb
index 00d40c4497..d0674eb03a 100644
--- a/activesupport/test/time_zone_test.rb
+++ b/activesupport/test/time_zone_test.rb
@@ -491,6 +491,11 @@ class TimeZoneTest < ActiveSupport::TestCase
assert !ActiveSupport::TimeZone.us_zones.include?(ActiveSupport::TimeZone["Kuala Lumpur"])
end
+ def test_country_zones
+ assert ActiveSupport::TimeZone.country_zones("ru").include?(ActiveSupport::TimeZone["Moscow"])
+ assert !ActiveSupport::TimeZone.country_zones(:ru).include?(ActiveSupport::TimeZone["Kuala Lumpur"])
+ end
+
def test_to_yaml
assert_equal("--- !ruby/object:ActiveSupport::TimeZone\nname: Pacific/Honolulu\n", ActiveSupport::TimeZone["Hawaii"].to_yaml)
assert_equal("--- !ruby/object:ActiveSupport::TimeZone\nname: Europe/London\n", ActiveSupport::TimeZone["Europe/London"].to_yaml)