Deprecate `to_s(format)` in favor of `to_formatted_s(format)`

Ruby 3.1 is going to introduce an [optimization][] that makes interpolation
of some types of objects faster, unless there is a custom implementation
of to_s. Since Rails is overriding `to_s` for a bunch of core classes it
means that this optimization in Rails applications will be disabled.

In order to allow Rails applications to use this optimization in
the future we are deprecating all the reasons we override `to_s` in
those core classes in favor of using `to_formatted_s`.

[optimization]: b08dacfea3
This commit is contained in:
Rafael Mendonça França 2021-12-03 06:16:59 +00:00
parent c2e12e0191
commit 58ecdd0cf2
No known key found for this signature in database
GPG Key ID: FC23B6D0F1EEE948
24 changed files with 841 additions and 412 deletions

View File

@ -26,7 +26,7 @@ module ActionController
#
# module FormattedTimeHelper
# def format_time(time, format=:long, blank_message=" ")
# time.blank? ? blank_message : time.to_s(format)
# time.blank? ? blank_message : time.to_formatted_s(format)
# end
# end
#

View File

@ -413,7 +413,7 @@ module ActiveRecord
inspected_value = if value.is_a?(String) && value.length > 50
"#{value[0, 50]}...".inspect
elsif value.is_a?(Date) || value.is_a?(Time)
%("#{value.to_s(:inspect)}")
%("#{value.to_formatted_s(:inspect)}")
else
value.inspect
end

View File

@ -79,7 +79,7 @@ module ActiveRecord
timestamp = max_updated_column_timestamp
if timestamp
timestamp = timestamp.utc.to_s(cache_timestamp_format)
timestamp = timestamp.utc.to_formatted_s(cache_timestamp_format)
"#{model_name.cache_key}/#{id}-#{timestamp}"
else
"#{model_name.cache_key}/#{id}"
@ -101,8 +101,9 @@ module ActiveRecord
timestamp = updated_at_before_type_cast
if can_use_fast_cache_version?(timestamp)
raw_timestamp_to_cache_version(timestamp)
elsif timestamp = updated_at
timestamp.utc.to_s(cache_timestamp_format)
timestamp.utc.to_formatted_s(cache_timestamp_format)
end
elsif self.class.has_attribute?("updated_at")
raise ActiveModel::MissingAttributeError, "missing attribute: updated_at"

View File

@ -389,7 +389,7 @@ module ActiveRecord
end
if timestamp
"#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}"
"#{size}-#{timestamp.utc.to_formatted_s(cache_timestamp_format)}"
else
"#{size}"
end

View File

@ -41,7 +41,7 @@ class AttributeMethodsTest < ActiveRecord::TestCase
test "attribute_for_inspect with a date" do
t = topics(:first)
assert_equal %("#{t.written_on.to_s(:inspect)}"), t.attribute_for_inspect(:written_on)
assert_equal %("#{t.written_on.to_formatted_s(:inspect)}"), t.attribute_for_inspect(:written_on)
end
test "attribute_for_inspect with an array" do

View File

@ -44,10 +44,10 @@ module ActiveRecord
test "cache_key_with_version always has both key and version" do
r1 = CacheMeWithVersion.create
assert_equal "active_record/cache_key_test/cache_me_with_versions/#{r1.id}-#{r1.updated_at.utc.to_s(:usec)}", r1.cache_key_with_version
assert_equal "active_record/cache_key_test/cache_me_with_versions/#{r1.id}-#{r1.updated_at.utc.to_formatted_s(:usec)}", r1.cache_key_with_version
r2 = CacheMe.create
assert_equal "active_record/cache_key_test/cache_mes/#{r2.id}-#{r2.updated_at.utc.to_s(:usec)}", r2.cache_key_with_version
assert_equal "active_record/cache_key_test/cache_mes/#{r2.id}-#{r2.updated_at.utc.to_formatted_s(:usec)}", r2.cache_key_with_version
end
test "cache_version is the same when it comes from the DB or from the user" do

View File

@ -27,7 +27,7 @@ module ActiveRecord
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $3
end
test "cache_key for relation with limit" do
@ -40,7 +40,7 @@ module ActiveRecord
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $3
end
test "cache_key for relation with custom select and limit" do
@ -54,7 +54,7 @@ module ActiveRecord
assert_equal ActiveSupport::Digest.hexdigest(developers_with_select.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $3
end
test "cache_key for loaded relation" do
@ -67,7 +67,7 @@ module ActiveRecord
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $3
end
test "cache_key for relation with table alias" do
@ -89,7 +89,7 @@ module ActiveRecord
assert_equal ActiveSupport::Digest.hexdigest(developers.to_sql), $1
assert_equal developers.count.to_s, $2
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $3
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $3
end
test "cache_key for relation with includes" do
@ -182,7 +182,7 @@ module ActiveRecord
test "cache_key with custom timestamp column" do
topics = Topic.where("title like ?", "%Topic%")
last_topic_timestamp = topics(:fifth).written_on.utc.to_s(:usec)
last_topic_timestamp = topics(:fifth).written_on.utc.to_formatted_s(:usec)
assert_match(last_topic_timestamp, topics.cache_key(:written_on))
end
@ -250,7 +250,7 @@ module ActiveRecord
/(\d+)-(\d+)\z/ =~ developers.cache_version
assert_equal developers.count.to_s, $1
assert_equal last_developer_timestamp.to_s(ActiveRecord::Base.cache_timestamp_format), $2
assert_equal last_developer_timestamp.to_formatted_s(ActiveRecord::Base.cache_timestamp_format), $2
end
end

View File

@ -18,7 +18,7 @@ class CoreTest < ActiveRecord::TestCase
def test_inspect_instance
topic = topics(:first)
assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:inspect)}", bonus_time: "#{topic.bonus_time.to_s(:inspect)}", last_read: "#{topic.last_read.to_s(:inspect)}", content: "Have a nice day", important: nil, approved: false, replies_count: 1, unique_replies_count: 0, parent_id: nil, parent_title: nil, type: nil, group: nil, created_at: "#{topic.created_at.to_s(:inspect)}", updated_at: "#{topic.updated_at.to_s(:inspect)}">), topic.inspect
assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_formatted_s(:inspect)}", bonus_time: "#{topic.bonus_time.to_formatted_s(:inspect)}", last_read: "#{topic.last_read.to_formatted_s(:inspect)}", content: "Have a nice day", important: nil, approved: false, replies_count: 1, unique_replies_count: 0, parent_id: nil, parent_title: nil, type: nil, group: nil, created_at: "#{topic.created_at.to_formatted_s(:inspect)}", updated_at: "#{topic.updated_at.to_formatted_s(:inspect)}">), topic.inspect
end
def test_inspect_instance_with_lambda_date_formatter

View File

@ -108,12 +108,12 @@ class IntegrationTest < ActiveRecord::TestCase
def test_cache_key_format_for_existing_record_with_updated_at
dev = Developer.first
assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_s(:usec)}", dev.cache_key
assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_formatted_s(:usec)}", dev.cache_key
end
def test_cache_key_format_for_existing_record_with_updated_at_and_custom_cache_timestamp_format
dev = CachedDeveloper.first
assert_equal "cached_developers/#{dev.id}-#{dev.updated_at.utc.to_s(:number)}", dev.cache_key
assert_equal "cached_developers/#{dev.id}-#{dev.updated_at.utc.to_formatted_s(:number)}", dev.cache_key
end
def test_cache_key_changes_when_child_touched
@ -138,19 +138,19 @@ class IntegrationTest < ActiveRecord::TestCase
def test_cache_key_for_updated_on
dev = Developer.first
dev.updated_at = nil
assert_equal "developers/#{dev.id}-#{dev.updated_on.utc.to_s(:usec)}", dev.cache_key
assert_equal "developers/#{dev.id}-#{dev.updated_on.utc.to_formatted_s(:usec)}", dev.cache_key
end
def test_cache_key_for_newer_updated_at
dev = Developer.first
dev.updated_at += 3600
assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_s(:usec)}", dev.cache_key
assert_equal "developers/#{dev.id}-#{dev.updated_at.utc.to_formatted_s(:usec)}", dev.cache_key
end
def test_cache_key_for_newer_updated_on
dev = Developer.first
dev.updated_on += 3600
assert_equal "developers/#{dev.id}-#{dev.updated_on.utc.to_s(:usec)}", dev.cache_key
assert_equal "developers/#{dev.id}-#{dev.updated_on.utc.to_formatted_s(:usec)}", dev.cache_key
end
def test_cache_key_format_is_precise_enough

View File

@ -103,7 +103,28 @@ class Array
end
end
alias_method :to_default_s, :to_s
alias_method :to_s, :to_formatted_s
NOT_SET = Object.new # :nodoc:
def to_s(format = NOT_SET)
case format
when :db
ActiveSupport::Deprecation.warn(
"Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_formatted_s(#{format.inspect}) instead."
)
if empty?
"null"
else
collect(&:id).join(",")
end
when NOT_SET
to_default_s
else
ActiveSupport::Deprecation.warn(
"Array#to_s(#{format.inspect}) is deprecated. Please use Array#to_formatted_s(#{format.inspect}) instead."
)
to_default_s
end
end
# Returns a string that represents the array in XML by invoking +to_xml+
# on each element. Active Record collections delegate their representation

View File

@ -27,7 +27,7 @@ class Date
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
#
# date.to_formatted_s(:db) # => "2007-11-10"
# date.to_formatted_s(:db) # => "2007-11-10"
# date.to_formatted_s(:db) # => "2007-11-10"
#
# date.to_formatted_s(:short) # => "10 Nov"
# date.to_formatted_s(:number) # => "20071110"
@ -56,7 +56,27 @@ class Date
end
end
alias_method :to_default_s, :to_s
alias_method :to_s, :to_formatted_s
NOT_SET = Object.new # :nodoc:
def to_s(format = NOT_SET) # :nodoc:
if formatter = DATE_FORMATS[format]
ActiveSupport::Deprecation.warn(
"Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_formatted_s(#{format.inspect}) instead."
)
if formatter.respond_to?(:call)
formatter.call(self).to_s
else
strftime(formatter)
end
elsif format == NOT_SET
to_default_s
else
ActiveSupport::Deprecation.warn(
"Date#to_s(#{format.inspect}) is deprecated. Please use Date#to_formatted_s(#{format.inspect}) instead."
)
to_default_s
end
end
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005"
def readable_inspect

View File

@ -9,14 +9,12 @@ require "active_support/values/time_zone"
class DateTime
# Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
#
# This method is aliased to <tt>to_s</tt>.
#
# === Examples
# datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
#
# datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
# datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
# datetime.to_s(:number) # => "20071204000000"
# datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
# datetime.to_formatted_s(:number) # => "20071204000000"
# datetime.to_formatted_s(:short) # => "04 Dec 00:00"
# datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
# datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
@ -40,7 +38,23 @@ class DateTime
end
end
alias_method :to_default_s, :to_s if instance_methods(false).include?(:to_s)
alias_method :to_s, :to_formatted_s
NOT_SET = Object.new # :nodoc:
def to_s(format = NOT_SET) # :nodoc:
if formatter = ::Time::DATE_FORMATS[format]
ActiveSupport::Deprecation.warn(
"DateTime#to_s(#{format.inspect}) is deprecated. Please use DateTime#to_formatted_s(#{format.inspect}) instead."
)
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
elsif format == NOT_SET
to_default_s
else
ActiveSupport::Deprecation.warn(
"DateTime#to_s(#{format.inspect}) is deprecated. Please use DateTime#to_formatted_s(#{format.inspect}) instead."
)
to_default_s
end
end
# Returns a formatted string of the offset from UTC, or an alternative
# string if the time zone is already UTC.
@ -54,7 +68,7 @@ class DateTime
# Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
def readable_inspect
to_s(:rfc822)
to_formatted_s(:rfc822)
end
alias_method :default_inspect, :inspect
alias_method :inspect, :readable_inspect

View File

@ -16,102 +16,102 @@ module ActiveSupport
# ==== Examples
#
# Phone Numbers:
# 5551234.to_s(:phone) # => "555-1234"
# 1235551234.to_s(:phone) # => "123-555-1234"
# 1235551234.to_s(:phone, area_code: true) # => "(123) 555-1234"
# 1235551234.to_s(:phone, delimiter: ' ') # => "123 555 1234"
# 1235551234.to_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
# 1235551234.to_s(:phone, country_code: 1) # => "+1-123-555-1234"
# 1235551234.to_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
# 5551234.to_formatted_s(:phone) # => "555-1234"
# 1235551234.to_formatted_s(:phone) # => "123-555-1234"
# 1235551234.to_formatted_s(:phone, area_code: true) # => "(123) 555-1234"
# 1235551234.to_formatted_s(:phone, delimiter: ' ') # => "123 555 1234"
# 1235551234.to_formatted_s(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
# 1235551234.to_formatted_s(:phone, country_code: 1) # => "+1-123-555-1234"
# 1235551234.to_formatted_s(:phone, country_code: 1, extension: 1343, delimiter: '.')
# # => "+1.123.555.1234 x 1343"
#
# Currency:
# 1234567890.50.to_s(:currency) # => "$1,234,567,890.50"
# 1234567890.506.to_s(:currency) # => "$1,234,567,890.51"
# 1234567890.506.to_s(:currency, precision: 3) # => "$1,234,567,890.506"
# 1234567890.506.to_s(:currency, round_mode: :down) # => "$1,234,567,890.50"
# 1234567890.506.to_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
# -1234567890.50.to_s(:currency, negative_format: '(%u%n)')
# 1234567890.50.to_formatted_s(:currency) # => "$1,234,567,890.50"
# 1234567890.506.to_formatted_s(:currency) # => "$1,234,567,890.51"
# 1234567890.506.to_formatted_s(:currency, precision: 3) # => "$1,234,567,890.506"
# 1234567890.506.to_formatted_s(:currency, round_mode: :down) # => "$1,234,567,890.50"
# 1234567890.506.to_formatted_s(:currency, locale: :fr) # => "1 234 567 890,51 €"
# -1234567890.50.to_formatted_s(:currency, negative_format: '(%u%n)')
# # => "($1,234,567,890.50)"
# 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
# 1234567890.50.to_formatted_s(:currency, unit: '&pound;', separator: ',', delimiter: '')
# # => "&pound;1234567890,50"
# 1234567890.50.to_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
# 1234567890.50.to_formatted_s(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
# # => "1234567890,50 &pound;"
#
# Percentage:
# 100.to_s(:percentage) # => "100.000%"
# 100.to_s(:percentage, precision: 0) # => "100%"
# 1000.to_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
# 302.24398923423.to_s(:percentage, precision: 5) # => "302.24399%"
# 302.24398923423.to_s(:percentage, round_mode: :down) # => "302.243%"
# 1000.to_s(:percentage, locale: :fr) # => "1 000,000%"
# 100.to_s(:percentage, format: '%n %') # => "100.000 %"
# 100.to_formatted_s(:percentage) # => "100.000%"
# 100.to_formatted_s(:percentage, precision: 0) # => "100%"
# 1000.to_formatted_s(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
# 302.24398923423.to_formatted_s(:percentage, precision: 5) # => "302.24399%"
# 302.24398923423.to_formatted_s(:percentage, round_mode: :down) # => "302.243%"
# 1000.to_formatted_s(:percentage, locale: :fr) # => "1 000,000%"
# 100.to_formatted_s(:percentage, format: '%n %') # => "100.000 %"
#
# Delimited:
# 12345678.to_s(:delimited) # => "12,345,678"
# 12345678.05.to_s(:delimited) # => "12,345,678.05"
# 12345678.to_s(:delimited, delimiter: '.') # => "12.345.678"
# 12345678.to_s(:delimited, delimiter: ',') # => "12,345,678"
# 12345678.05.to_s(:delimited, separator: ' ') # => "12,345,678 05"
# 12345678.05.to_s(:delimited, locale: :fr) # => "12 345 678,05"
# 98765432.98.to_s(:delimited, delimiter: ' ', separator: ',')
# 12345678.to_formatted_s(:delimited) # => "12,345,678"
# 12345678.05.to_formatted_s(:delimited) # => "12,345,678.05"
# 12345678.to_formatted_s(:delimited, delimiter: '.') # => "12.345.678"
# 12345678.to_formatted_s(:delimited, delimiter: ',') # => "12,345,678"
# 12345678.05.to_formatted_s(:delimited, separator: ' ') # => "12,345,678 05"
# 12345678.05.to_formatted_s(:delimited, locale: :fr) # => "12 345 678,05"
# 98765432.98.to_formatted_s(:delimited, delimiter: ' ', separator: ',')
# # => "98 765 432,98"
#
# Rounded:
# 111.2345.to_s(:rounded) # => "111.235"
# 111.2345.to_s(:rounded, precision: 2) # => "111.23"
# 111.2345.to_s(:rounded, precision: 2, round_mode: :up) # => "111.24"
# 13.to_s(:rounded, precision: 5) # => "13.00000"
# 389.32314.to_s(:rounded, precision: 0) # => "389"
# 111.2345.to_s(:rounded, significant: true) # => "111"
# 111.2345.to_s(:rounded, precision: 1, significant: true) # => "100"
# 13.to_s(:rounded, precision: 5, significant: true) # => "13.000"
# 111.234.to_s(:rounded, locale: :fr) # => "111,234"
# 13.to_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
# 111.2345.to_formatted_s(:rounded) # => "111.235"
# 111.2345.to_formatted_s(:rounded, precision: 2) # => "111.23"
# 111.2345.to_formatted_s(:rounded, precision: 2, round_mode: :up) # => "111.24"
# 13.to_formatted_s(:rounded, precision: 5) # => "13.00000"
# 389.32314.to_formatted_s(:rounded, precision: 0) # => "389"
# 111.2345.to_formatted_s(:rounded, significant: true) # => "111"
# 111.2345.to_formatted_s(:rounded, precision: 1, significant: true) # => "100"
# 13.to_formatted_s(:rounded, precision: 5, significant: true) # => "13.000"
# 111.234.to_formatted_s(:rounded, locale: :fr) # => "111,234"
# 13.to_formatted_s(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
# # => "13"
# 389.32314.to_s(:rounded, precision: 4, significant: true) # => "389.3"
# 1111.2345.to_s(:rounded, precision: 2, separator: ',', delimiter: '.')
# 389.32314.to_formatted_s(:rounded, precision: 4, significant: true) # => "389.3"
# 1111.2345.to_formatted_s(:rounded, precision: 2, separator: ',', delimiter: '.')
# # => "1.111,23"
#
# Human-friendly size in Bytes:
# 123.to_s(:human_size) # => "123 Bytes"
# 1234.to_s(:human_size) # => "1.21 KB"
# 12345.to_s(:human_size) # => "12.1 KB"
# 1234567.to_s(:human_size) # => "1.18 MB"
# 1234567890.to_s(:human_size) # => "1.15 GB"
# 1234567890123.to_s(:human_size) # => "1.12 TB"
# 1234567890123456.to_s(:human_size) # => "1.1 PB"
# 1234567890123456789.to_s(:human_size) # => "1.07 EB"
# 1234567.to_s(:human_size, precision: 2) # => "1.2 MB"
# 1234567.to_s(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
# 483989.to_s(:human_size, precision: 2) # => "470 KB"
# 1234567.to_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
# 1234567890123.to_s(:human_size, precision: 5) # => "1.1228 TB"
# 524288000.to_s(:human_size, precision: 5) # => "500 MB"
# 123.to_formatted_s(:human_size) # => "123 Bytes"
# 1234.to_formatted_s(:human_size) # => "1.21 KB"
# 12345.to_formatted_s(:human_size) # => "12.1 KB"
# 1234567.to_formatted_s(:human_size) # => "1.18 MB"
# 1234567890.to_formatted_s(:human_size) # => "1.15 GB"
# 1234567890123.to_formatted_s(:human_size) # => "1.12 TB"
# 1234567890123456.to_formatted_s(:human_size) # => "1.1 PB"
# 1234567890123456789.to_formatted_s(:human_size) # => "1.07 EB"
# 1234567.to_formatted_s(:human_size, precision: 2) # => "1.2 MB"
# 1234567.to_formatted_s(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
# 483989.to_formatted_s(:human_size, precision: 2) # => "470 KB"
# 1234567.to_formatted_s(:human_size, precision: 2, separator: ',') # => "1,2 MB"
# 1234567890123.to_formatted_s(:human_size, precision: 5) # => "1.1228 TB"
# 524288000.to_formatted_s(:human_size, precision: 5) # => "500 MB"
#
# Human-friendly format:
# 123.to_s(:human) # => "123"
# 1234.to_s(:human) # => "1.23 Thousand"
# 12345.to_s(:human) # => "12.3 Thousand"
# 1234567.to_s(:human) # => "1.23 Million"
# 1234567890.to_s(:human) # => "1.23 Billion"
# 1234567890123.to_s(:human) # => "1.23 Trillion"
# 1234567890123456.to_s(:human) # => "1.23 Quadrillion"
# 1234567890123456789.to_s(:human) # => "1230 Quadrillion"
# 489939.to_s(:human, precision: 2) # => "490 Thousand"
# 489939.to_s(:human, precision: 2, round_mode: :down) # => "480 Thousand"
# 489939.to_s(:human, precision: 4) # => "489.9 Thousand"
# 1234567.to_s(:human, precision: 4,
# significant: false) # => "1.2346 Million"
# 1234567.to_s(:human, precision: 1,
# 123.to_formatted_s(:human) # => "123"
# 1234.to_formatted_s(:human) # => "1.23 Thousand"
# 12345.to_formatted_s(:human) # => "12.3 Thousand"
# 1234567.to_formatted_s(:human) # => "1.23 Million"
# 1234567890.to_formatted_s(:human) # => "1.23 Billion"
# 1234567890123.to_formatted_s(:human) # => "1.23 Trillion"
# 1234567890123456.to_formatted_s(:human) # => "1.23 Quadrillion"
# 1234567890123456789.to_formatted_s(:human) # => "1230 Quadrillion"
# 489939.to_formatted_s(:human, precision: 2) # => "490 Thousand"
# 489939.to_formatted_s(:human, precision: 2, round_mode: :down) # => "480 Thousand"
# 489939.to_formatted_s(:human, precision: 4) # => "489.9 Thousand"
# 1234567.to_formatted_s(:human, precision: 4,
# significant: false) # => "1.2346 Million"
# 1234567.to_formatted_s(:human, precision: 1,
# separator: ',',
# significant: false) # => "1,2 Million"
def to_s(format = nil, options = nil)
return super() if format.nil?
# significant: false) # => "1,2 Million"
def to_formatted_s(format = nil, options = nil)
return to_s if format.nil?
case format
when Integer, String
super(format)
to_s(format)
when :phone
ActiveSupport::NumberHelper.number_to_phone(self, options || {})
when :currency
@ -127,12 +127,62 @@ module ActiveSupport
when :human_size
ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
when Symbol
to_s
else
to_s(format)
end
end
def to_s(format = nil, options = nil) # :nodoc:
return super() if format.nil?
case format
when Integer, String
super(format)
when :phone
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_phone(self, options || {})
when :currency
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_currency(self, options || {})
when :percentage
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_percentage(self, options || {})
when :delimited
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_delimited(self, options || {})
when :rounded
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_rounded(self, options || {})
when :human
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_human(self, options || {})
when :human_size
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
ActiveSupport::NumberHelper.number_to_human_size(self, options || {})
when Symbol
ActiveSupport::Deprecation.warn(
"#{self.class}#to_s(#{format.inspect}) is deprecated. Please use #{self.class}#to_formatted_s(#{format.inspect}) instead."
)
super()
else
super(format)
end
end
alias_method :to_formatted_s, :to_s
end
end

View File

@ -12,6 +12,25 @@ module ActiveSupport
end
}
NOT_SET = Object.new # :nodoc:
def to_s(format = NOT_SET) # :nodoc:
if formatter = RANGE_FORMATS[format]
ActiveSupport::Deprecation.warn(
"Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
)
formatter.call(first, last)
elsif format == NOT_SET
super()
else
ActiveSupport::Deprecation.warn(
"Range#to_s(#{format.inspect}) is deprecated. Please use Range#to_formatted_s(#{format.inspect}) instead."
)
super()
end
end
alias_method :to_default_s, :to_s
deprecate :to_default_s
# Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
#
# range = (1..100) # => 1..100
@ -25,16 +44,13 @@ module ActiveSupport
#
# # config/initializers/range_formats.rb
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_formatted_s(:db)} and #{stop.to_formatted_s(:db)}" }
def to_s(format = :default)
def to_formatted_s(format = :default)
if formatter = RANGE_FORMATS[format]
formatter.call(first, last)
else
super()
to_s
end
end
alias_method :to_default_s, :to_s
alias_method :to_formatted_s, :to_s
end
end

View File

@ -27,12 +27,10 @@ class Time
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
#
# This method is aliased to <tt>to_s</tt>.
#
# time = Time.now # => 2007-01-18 06:10:17 -06:00
#
# time.to_formatted_s(:time) # => "06:10"
# time.to_s(:time) # => "06:10"
# time.to_formatted_s(:time) # => "06:10"
#
# time.to_formatted_s(:db) # => "2007-01-18 06:10:17"
# time.to_formatted_s(:number) # => "20070118061017"
@ -54,11 +52,28 @@ class Time
if formatter = DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
else
# Change to `to_s` when deprecation is gone. Also deprecate `to_default_s`.
to_default_s
end
end
alias_method :to_default_s, :to_s
alias_method :to_s, :to_formatted_s
NOT_SET = Object.new # :nodoc:
def to_s(format = NOT_SET) # :nodoc:
if formatter = DATE_FORMATS[format]
ActiveSupport::Deprecation.warn(
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
)
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
elsif format == NOT_SET
to_default_s
else
ActiveSupport::Deprecation.warn(
"Time#to_s(#{format.inspect}) is deprecated. Please use Time#to_formatted_s(#{format.inspect}) instead."
)
to_default_s
end
end
# Returns a formatted string of the offset from UTC, or an alternative
# string if the time zone is already UTC.

View File

@ -33,7 +33,7 @@ module ActiveSupport
# t.dst? # => true
# t.utc_offset # => -14400
# t.zone # => "EDT"
# t.to_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
# t.to_formatted_s(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400"
# t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
# t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00
# t > Time.utc(1999) # => true
@ -202,25 +202,49 @@ module ActiveSupport
#
# Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000"
def rfc2822
to_s(:rfc822)
to_formatted_s(:rfc822)
end
alias_method :rfc822, :rfc2822
NOT_SET = Object.new # :nodoc:
# Returns a string of the object's date and time.
def to_s(format = NOT_SET)
if format == :db
ActiveSupport::Deprecation.warn(
"TimeWithZone#to_s(:db) is deprecated. Please use TimeWithZone#to_formatted_s(:db) instead."
)
utc.to_formatted_s(format)
elsif formatter = ::Time::DATE_FORMATS[format]
ActiveSupport::Deprecation.warn(
"TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_formatted_s(#{format.inspect}) instead."
)
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
elsif format == NOT_SET
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
else
ActiveSupport::Deprecation.warn(
"TimeWithZone#to_s(#{format.inspect}) is deprecated. Please use TimeWithZone#to_formatted_s(#{format.inspect}) instead."
)
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
end
end
# Returns a string of the object's date and time.
# Accepts an optional <tt>format</tt>:
# * <tt>:default</tt> - default value, mimics Ruby Time#to_s format.
# * <tt>:db</tt> - format outputs time in UTC :db time. See Time#to_formatted_s(:db).
# * Any key in <tt>Time::DATE_FORMATS</tt> can be used. See active_support/core_ext/time/conversions.rb.
def to_s(format = :default)
def to_formatted_s(format = :default)
if format == :db
utc.to_s(format)
utc.to_formatted_s(format)
elsif formatter = ::Time::DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
else
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
# Change to to_s when deprecation is gone.
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}"
end
end
alias_method :to_formatted_s, :to_s
# Replaces <tt>%Z</tt> directive with +zone before passing to Time#strftime,
# so that zone information is correct.

View File

@ -79,15 +79,41 @@ end
class ToSTest < ActiveSupport::TestCase
class TestDB
@@counter = 0
def self.reset
@@counter = 0
end
reset
def id
@@counter += 1
end
end
setup do
TestDB.reset
end
def test_to_s_db
collection = [TestDB.new, TestDB.new, TestDB.new]
assert_deprecated do
assert_equal "null", [].to_s(:db)
end
assert_deprecated do
assert_equal "1,2,3", collection.to_s(:db)
end
end
def test_to_s_not_existent
assert_deprecated do
assert_equal "[]", [].to_s(:not_existent)
end
end
def test_to_formatted_s_db
collection = [TestDB.new, TestDB.new, TestDB.new]
assert_equal "null", [].to_formatted_s(:db)
assert_equal "1,2,3", collection.to_formatted_s(:db)
end

View File

@ -24,25 +24,81 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
def test_to_s
date = Date.new(2005, 2, 21)
assert_equal "2005-02-21", date.to_s
assert_equal "21 Feb", date.to_s(:short)
assert_equal "February 21, 2005", date.to_s(:long)
assert_equal "February 21st, 2005", date.to_s(:long_ordinal)
assert_equal "2005-02-21", date.to_formatted_s(:db)
assert_equal "2005-02-21", date.to_s(:inspect)
assert_equal "21 Feb 2005", date.to_s(:rfc822)
assert_equal "2005-02-21", date.to_s(:iso8601)
assert_deprecated do
assert_equal "21 Feb", date.to_s(:short)
end
assert_deprecated do
assert_equal "February 21, 2005", date.to_s(:long)
end
assert_deprecated do
assert_equal "February 21st, 2005", date.to_s(:long_ordinal)
end
assert_deprecated do
assert_equal "2005-02-21", date.to_s(:db)
end
assert_deprecated do
assert_equal "2005-02-21", date.to_s(:inspect)
end
assert_deprecated do
assert_equal "21 Feb 2005", date.to_s(:rfc822)
end
assert_deprecated do
assert_equal "2005-02-21", date.to_s(:iso8601)
end
assert_deprecated do
assert_equal "2005-02-21", date.to_s(:not_existent)
end
end
def test_to_s_with_single_digit_day
date = Date.new(2005, 2, 1)
assert_equal "2005-02-01", date.to_s
assert_equal "01 Feb", date.to_s(:short)
assert_equal "February 01, 2005", date.to_s(:long)
assert_equal "February 1st, 2005", date.to_s(:long_ordinal)
assert_deprecated do
assert_equal "01 Feb", date.to_s(:short)
end
assert_deprecated do
assert_equal "February 01, 2005", date.to_s(:long)
end
assert_deprecated do
assert_equal "February 1st, 2005", date.to_s(:long_ordinal)
end
assert_deprecated do
assert_equal "2005-02-01", date.to_s(:db)
end
assert_deprecated do
assert_equal "2005-02-01", date.to_s(:inspect)
end
assert_deprecated do
assert_equal "01 Feb 2005", date.to_s(:rfc822)
end
assert_deprecated do
assert_equal "2005-02-01", date.to_s(:iso8601)
end
assert_deprecated do
assert_equal "2005-02-01", date.to_s(:not_existent)
end
end
def test_to_formatted_s
date = Date.new(2005, 2, 21)
assert_equal "21 Feb", date.to_formatted_s(:short)
assert_equal "February 21, 2005", date.to_formatted_s(:long)
assert_equal "February 21st, 2005", date.to_formatted_s(:long_ordinal)
assert_equal "2005-02-21", date.to_formatted_s(:db)
assert_equal "2005-02-21", date.to_formatted_s(:inspect)
assert_equal "21 Feb 2005", date.to_formatted_s(:rfc822)
assert_equal "2005-02-21", date.to_formatted_s(:iso8601)
end
def test_to_formatted_s_with_single_digit_day
date = Date.new(2005, 2, 1)
assert_equal "01 Feb", date.to_formatted_s(:short)
assert_equal "February 01, 2005", date.to_formatted_s(:long)
assert_equal "February 1st, 2005", date.to_formatted_s(:long_ordinal)
assert_equal "2005-02-01", date.to_formatted_s(:db)
assert_equal "2005-02-01", date.to_s(:inspect)
assert_equal "01 Feb 2005", date.to_s(:rfc822)
assert_equal "2005-02-01", date.to_s(:iso8601)
assert_equal "2005-02-01", date.to_formatted_s(:inspect)
assert_equal "01 Feb 2005", date.to_formatted_s(:rfc822)
assert_equal "2005-02-01", date.to_formatted_s(:iso8601)
end
def test_readable_inspect

View File

@ -15,19 +15,61 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
def test_to_s
datetime = DateTime.new(2005, 2, 21, 14, 30, 0, 0)
assert_equal "2005-02-21 14:30:00", datetime.to_formatted_s(:db)
assert_equal "2005-02-21 14:30:00.000000000 +0000", datetime.to_s(:inspect)
assert_equal "14:30", datetime.to_s(:time)
assert_equal "21 Feb 14:30", datetime.to_s(:short)
assert_equal "February 21, 2005 14:30", datetime.to_s(:long)
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.to_s(:rfc822)
assert_equal "February 21st, 2005 14:30", datetime.to_s(:long_ordinal)
assert_deprecated do
assert_equal "2005-02-21 14:30:00", datetime.to_s(:db)
end
assert_deprecated do
assert_equal "2005-02-21 14:30:00.000000000 +0000", datetime.to_s(:inspect)
end
assert_deprecated do
assert_equal "14:30", datetime.to_s(:time)
end
assert_deprecated do
assert_equal "21 Feb 14:30", datetime.to_s(:short)
end
assert_deprecated do
assert_equal "February 21, 2005 14:30", datetime.to_s(:long)
end
assert_deprecated do
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.to_s(:rfc822)
end
assert_deprecated do
assert_equal "February 21st, 2005 14:30", datetime.to_s(:long_ordinal)
end
assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/, datetime.to_s)
assert_deprecated do
assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/, datetime.to_s(:not_existent))
end
with_env_tz "US/Central" do
assert_equal "2009-02-05T14:30:05-06:00", DateTime.civil(2009, 2, 5, 14, 30, 5, Rational(-21600, 86400)).to_s(:iso8601)
assert_equal "2008-06-09T04:05:01-05:00", DateTime.civil(2008, 6, 9, 4, 5, 1, Rational(-18000, 86400)).to_s(:iso8601)
assert_equal "2009-02-05T14:30:05+00:00", DateTime.civil(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
assert_deprecated do
assert_equal "2009-02-05T14:30:05-06:00", DateTime.civil(2009, 2, 5, 14, 30, 5, Rational(-21600, 86400)).to_s(:iso8601)
end
assert_deprecated do
assert_equal "2008-06-09T04:05:01-05:00", DateTime.civil(2008, 6, 9, 4, 5, 1, Rational(-18000, 86400)).to_s(:iso8601)
end
assert_deprecated do
assert_equal "2009-02-05T14:30:05+00:00", DateTime.civil(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
end
end
end
def test_to_formatted_s
datetime = DateTime.new(2005, 2, 21, 14, 30, 0, 0)
assert_equal "2005-02-21 14:30:00", datetime.to_formatted_s(:db)
assert_equal "2005-02-21 14:30:00.000000000 +0000", datetime.to_formatted_s(:inspect)
assert_equal "14:30", datetime.to_formatted_s(:time)
assert_equal "21 Feb 14:30", datetime.to_formatted_s(:short)
assert_equal "February 21, 2005 14:30", datetime.to_formatted_s(:long)
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.to_formatted_s(:rfc822)
assert_equal "February 21st, 2005 14:30", datetime.to_formatted_s(:long_ordinal)
assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/, datetime.to_formatted_s)
assert_match(/^2005-02-21T14:30:00(Z|\+00:00)$/, datetime.to_formatted_s(:not_existent))
with_env_tz "US/Central" do
assert_equal "2009-02-05T14:30:05-06:00", DateTime.civil(2009, 2, 5, 14, 30, 5, Rational(-21600, 86400)).to_formatted_s(:iso8601)
assert_equal "2008-06-09T04:05:01-05:00", DateTime.civil(2008, 6, 9, 4, 5, 1, Rational(-18000, 86400)).to_formatted_s(:iso8601)
assert_equal "2009-02-05T14:30:05+00:00", DateTime.civil(2009, 2, 5, 14, 30, 5).to_formatted_s(:iso8601)
end
end
@ -37,9 +79,19 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase
assert_equal datetime.readable_inspect, datetime.inspect
end
def test_custom_date_format
def test_to_s_with_custom_date_format
Time::DATE_FORMATS[:custom] = "%Y%m%d%H%M%S"
assert_equal "20050221143000", DateTime.new(2005, 2, 21, 14, 30, 0).to_s(:custom)
assert_deprecated do
assert_equal "20050221143000", DateTime.new(2005, 2, 21, 14, 30, 0).to_s(:custom)
end
ensure
Time::DATE_FORMATS.delete(:custom)
end
def test_to_formatted_s_with_custom_date_format
Time::DATE_FORMATS[:custom] = "%Y%m%d%H%M%S"
assert_equal "20050221143000", DateTime.new(2005, 2, 21, 14, 30, 0).to_formatted_s(:custom)
ensure
Time::DATE_FORMATS.delete(:custom)
end

View File

@ -73,6 +73,10 @@ class NumericExtTimeAndDateTimeTest < ActiveSupport::TestCase
assert_equal Time.utc(2005, 2, 28, 15, 15, 10), Time.utc(2004, 2, 29, 15, 15, 10) + 1.year
assert_equal DateTime.civil(2005, 2, 28, 15, 15, 10), DateTime.civil(2004, 2, 29, 15, 15, 10) + 1.year
end
def test_in_milliseconds
assert_equal 10_000, 10.seconds.in_milliseconds
end
end
class NumericExtDateTest < ActiveSupport::TestCase
@ -153,262 +157,292 @@ class NumericExtFormattingTest < ActiveSupport::TestCase
petabytes(number) * 1024
end
def test_to_s__phone
assert_equal("555-1234", 5551234.to_s(:phone))
assert_equal("800-555-1212", 8005551212.to_s(:phone))
assert_equal("(800) 555-1212", 8005551212.to_s(:phone, area_code: true))
assert_equal("800 555 1212", 8005551212.to_s(:phone, delimiter: " "))
assert_equal("(800) 555-1212 x 123", 8005551212.to_s(:phone, area_code: true, extension: 123))
assert_equal("800-555-1212", 8005551212.to_s(:phone, extension: " "))
assert_equal("555.1212", 5551212.to_s(:phone, delimiter: "."))
assert_equal("+1-800-555-1212", 8005551212.to_s(:phone, country_code: 1))
assert_equal("+18005551212", 8005551212.to_s(:phone, country_code: 1, delimiter: ""))
assert_equal("22-555-1212", 225551212.to_s(:phone))
assert_equal("+45-22-555-1212", 225551212.to_s(:phone, country_code: 45))
def test_to_formatted_s__phone
assert_deprecated do
assert_equal("555-1234", 5551234.to_s(:phone))
end
assert_equal("555-1234", 5551234.to_formatted_s(:phone))
assert_equal("800-555-1212", 8005551212.to_formatted_s(:phone))
assert_equal("(800) 555-1212", 8005551212.to_formatted_s(:phone, area_code: true))
assert_equal("800 555 1212", 8005551212.to_formatted_s(:phone, delimiter: " "))
assert_equal("(800) 555-1212 x 123", 8005551212.to_formatted_s(:phone, area_code: true, extension: 123))
assert_equal("800-555-1212", 8005551212.to_formatted_s(:phone, extension: " "))
assert_equal("555.1212", 5551212.to_formatted_s(:phone, delimiter: "."))
assert_equal("+1-800-555-1212", 8005551212.to_formatted_s(:phone, country_code: 1))
assert_equal("+18005551212", 8005551212.to_formatted_s(:phone, country_code: 1, delimiter: ""))
assert_equal("22-555-1212", 225551212.to_formatted_s(:phone))
assert_equal("+45-22-555-1212", 225551212.to_formatted_s(:phone, country_code: 45))
end
def test_to_s__currency
assert_equal("$1,234,567,890.50", 1234567890.50.to_s(:currency))
assert_equal("$1,234,567,890.51", 1234567890.506.to_s(:currency))
assert_equal("-$1,234,567,890.50", -1234567890.50.to_s(:currency))
assert_equal("-$ 1,234,567,890.50", -1234567890.50.to_s(:currency, format: "%u %n"))
assert_equal("($1,234,567,890.50)", -1234567890.50.to_s(:currency, negative_format: "(%u%n)"))
assert_equal("$1,234,567,892", 1234567891.50.to_s(:currency, precision: 0))
assert_equal("$1,234,567,891", 1234567891.50.to_s(:currency, precision: 0, round_mode: :down))
assert_equal("$1,234,567,890.5", 1234567890.50.to_s(:currency, precision: 1))
assert_equal("&pound;1234567890,50", 1234567890.50.to_s(:currency, unit: "&pound;", separator: ",", delimiter: ""))
def test_to_formatted_s__currency
assert_deprecated do
assert_equal("$1,234,567,890.50", 1234567890.50.to_s(:currency))
end
assert_equal("$1,234,567,890.50", 1234567890.50.to_formatted_s(:currency))
assert_equal("$1,234,567,890.51", 1234567890.506.to_formatted_s(:currency))
assert_equal("-$1,234,567,890.50", -1234567890.50.to_formatted_s(:currency))
assert_equal("-$ 1,234,567,890.50", -1234567890.50.to_formatted_s(:currency, format: "%u %n"))
assert_equal("($1,234,567,890.50)", -1234567890.50.to_formatted_s(:currency, negative_format: "(%u%n)"))
assert_equal("$1,234,567,892", 1234567891.50.to_formatted_s(:currency, precision: 0))
assert_equal("$1,234,567,891", 1234567891.50.to_formatted_s(:currency, precision: 0, round_mode: :down))
assert_equal("$1,234,567,890.5", 1234567890.50.to_formatted_s(:currency, precision: 1))
assert_equal("&pound;1234567890,50", 1234567890.50.to_formatted_s(:currency, unit: "&pound;", separator: ",", delimiter: ""))
end
def test_to_s__rounded
assert_equal("-111.235", -111.2346.to_s(:rounded))
assert_equal("111.235", 111.2346.to_s(:rounded))
assert_equal("31.83", 31.825.to_s(:rounded, precision: 2))
assert_equal("31.82", 31.825.to_s(:rounded, precision: 2, round_mode: :down))
assert_equal("111.23", 111.2346.to_s(:rounded, precision: 2))
assert_equal("111.00", 111.to_s(:rounded, precision: 2))
assert_equal("3268", (32.6751 * 100.00).to_s(:rounded, precision: 0))
assert_equal("112", 111.50.to_s(:rounded, precision: 0))
assert_equal("1234567892", 1234567891.50.to_s(:rounded, precision: 0))
assert_equal("0", 0.to_s(:rounded, precision: 0))
assert_equal("0.00100", 0.001.to_s(:rounded, precision: 5))
assert_equal("0.001", 0.00111.to_s(:rounded, precision: 3))
assert_equal("10.00", 9.995.to_s(:rounded, precision: 2))
assert_equal("11.00", 10.995.to_s(:rounded, precision: 2))
assert_equal("0.00", -0.001.to_s(:rounded, precision: 2))
def test_to_formatted_s__rounded
assert_deprecated do
assert_equal("-111.235", -111.2346.to_s(:rounded))
end
assert_equal("-111.235", -111.2346.to_formatted_s(:rounded))
assert_equal("111.235", 111.2346.to_formatted_s(:rounded))
assert_equal("31.83", 31.825.to_formatted_s(:rounded, precision: 2))
assert_equal("31.82", 31.825.to_formatted_s(:rounded, precision: 2, round_mode: :down))
assert_equal("111.23", 111.2346.to_formatted_s(:rounded, precision: 2))
assert_equal("111.00", 111.to_formatted_s(:rounded, precision: 2))
assert_equal("3268", (32.6751 * 100.00).to_formatted_s(:rounded, precision: 0))
assert_equal("112", 111.50.to_formatted_s(:rounded, precision: 0))
assert_equal("1234567892", 1234567891.50.to_formatted_s(:rounded, precision: 0))
assert_equal("0", 0.to_formatted_s(:rounded, precision: 0))
assert_equal("0.00100", 0.001.to_formatted_s(:rounded, precision: 5))
assert_equal("0.001", 0.00111.to_formatted_s(:rounded, precision: 3))
assert_equal("10.00", 9.995.to_formatted_s(:rounded, precision: 2))
assert_equal("11.00", 10.995.to_formatted_s(:rounded, precision: 2))
assert_equal("0.00", -0.001.to_formatted_s(:rounded, precision: 2))
end
def test_to_s__percentage
assert_equal("100.000%", 100.to_s(:percentage))
assert_equal("100%", 100.to_s(:percentage, precision: 0))
assert_equal("302.06%", 302.0574.to_s(:percentage, precision: 2))
assert_equal("302.05%", 302.0574.to_s(:percentage, precision: 2, round_mode: :down))
assert_equal("123.4%", 123.400.to_s(:percentage, precision: 3, strip_insignificant_zeros: true))
assert_equal("1.000,000%", 1000.to_s(:percentage, delimiter: ".", separator: ","))
assert_equal("1000.000 %", 1000.to_s(:percentage, format: "%n %"))
def test_to_formatted_s__rounded_with_custom_delimiter_and_separator
assert_equal "31,83", 31.825.to_formatted_s(:rounded, precision: 2, separator: ",")
assert_equal "1.231,83", 1231.825.to_formatted_s(:rounded, precision: 2, separator: ",", delimiter: ".")
end
def test_to_s__delimited
assert_equal("12,345,678", 12345678.to_s(:delimited))
assert_equal("0", 0.to_s(:delimited))
assert_equal("123", 123.to_s(:delimited))
assert_equal("123,456", 123456.to_s(:delimited))
assert_equal("123,456.78", 123456.78.to_s(:delimited))
assert_equal("123,456.789", 123456.789.to_s(:delimited))
assert_equal("123,456.78901", 123456.78901.to_s(:delimited))
assert_equal("123,456,789.78901", 123456789.78901.to_s(:delimited))
assert_equal("0.78901", 0.78901.to_s(:delimited))
def test_to_formatted_s__rounded__with_significant_digits
assert_equal "124000", 123987.to_formatted_s(:rounded, precision: 3, significant: true)
assert_equal "120000000", 123987876.to_formatted_s(:rounded, precision: 2, significant: true)
assert_equal "9775", 9775.to_formatted_s(:rounded, precision: 4, significant: true)
assert_equal "5.4", 5.3923.to_formatted_s(:rounded, precision: 2, significant: true)
assert_equal "5", 5.3923.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "1", 1.232.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "7", 7.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "1", 1.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "53", 52.7923.to_formatted_s(:rounded, precision: 2, significant: true)
assert_equal "9775.00", 9775.to_formatted_s(:rounded, precision: 6, significant: true)
assert_equal "5.392900", 5.3929.to_formatted_s(:rounded, precision: 7, significant: true)
assert_equal "0.0", 0.to_formatted_s(:rounded, precision: 2, significant: true)
assert_equal "0", 0.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "0.0001", 0.0001.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "0.000100", 0.0001.to_formatted_s(:rounded, precision: 3, significant: true)
assert_equal "0.0001", 0.0001111.to_formatted_s(:rounded, precision: 1, significant: true)
assert_equal "10.0", 9.995.to_formatted_s(:rounded, precision: 3, significant: true)
assert_equal "9.99", 9.994.to_formatted_s(:rounded, precision: 3, significant: true)
assert_equal "11.0", 10.995.to_formatted_s(:rounded, precision: 3, significant: true)
assert_equal "10.9", 10.995.to_formatted_s(:rounded, precision: 3, significant: true, round_mode: :down)
end
def test_to_s__delimited__with_options_hash
assert_equal "12 345 678", 12345678.to_s(:delimited, delimiter: " ")
assert_equal "12,345,678-05", 12345678.05.to_s(:delimited, separator: "-")
assert_equal "12.345.678,05", 12345678.05.to_s(:delimited, separator: ",", delimiter: ".")
assert_equal "12.345.678,05", 12345678.05.to_s(:delimited, delimiter: ".", separator: ",")
def test_to_formatted_s__rounded__with_strip_insignificant_zeros
assert_equal "9775.43", 9775.43.to_formatted_s(:rounded, precision: 4, strip_insignificant_zeros: true)
assert_equal "9775.2", 9775.2.to_formatted_s(:rounded, precision: 6, significant: true, strip_insignificant_zeros: true)
assert_equal "0", 0.to_formatted_s(:rounded, precision: 6, significant: true, strip_insignificant_zeros: true)
end
def test_to_s__rounded_with_custom_delimiter_and_separator
assert_equal "31,83", 31.825.to_s(:rounded, precision: 2, separator: ",")
assert_equal "1.231,83", 1231.825.to_s(:rounded, precision: 2, separator: ",", delimiter: ".")
end
def test_to_s__rounded__with_significant_digits
assert_equal "124000", 123987.to_s(:rounded, precision: 3, significant: true)
assert_equal "120000000", 123987876.to_s(:rounded, precision: 2, significant: true)
assert_equal "9775", 9775.to_s(:rounded, precision: 4, significant: true)
assert_equal "5.4", 5.3923.to_s(:rounded, precision: 2, significant: true)
assert_equal "5", 5.3923.to_s(:rounded, precision: 1, significant: true)
assert_equal "1", 1.232.to_s(:rounded, precision: 1, significant: true)
assert_equal "7", 7.to_s(:rounded, precision: 1, significant: true)
assert_equal "1", 1.to_s(:rounded, precision: 1, significant: true)
assert_equal "53", 52.7923.to_s(:rounded, precision: 2, significant: true)
assert_equal "9775.00", 9775.to_s(:rounded, precision: 6, significant: true)
assert_equal "5.392900", 5.3929.to_s(:rounded, precision: 7, significant: true)
assert_equal "0.0", 0.to_s(:rounded, precision: 2, significant: true)
assert_equal "0", 0.to_s(:rounded, precision: 1, significant: true)
assert_equal "0.0001", 0.0001.to_s(:rounded, precision: 1, significant: true)
assert_equal "0.000100", 0.0001.to_s(:rounded, precision: 3, significant: true)
assert_equal "0.0001", 0.0001111.to_s(:rounded, precision: 1, significant: true)
assert_equal "10.0", 9.995.to_s(:rounded, precision: 3, significant: true)
assert_equal "9.99", 9.994.to_s(:rounded, precision: 3, significant: true)
assert_equal "11.0", 10.995.to_s(:rounded, precision: 3, significant: true)
assert_equal "10.9", 10.995.to_s(:rounded, precision: 3, significant: true, round_mode: :down)
end
def test_to_s__rounded__with_strip_insignificant_zeros
assert_equal "9775.43", 9775.43.to_s(:rounded, precision: 4, strip_insignificant_zeros: true)
assert_equal "9775.2", 9775.2.to_s(:rounded, precision: 6, significant: true, strip_insignificant_zeros: true)
assert_equal "0", 0.to_s(:rounded, precision: 6, significant: true, strip_insignificant_zeros: true)
end
def test_to_s__rounded__with_significant_true_and_zero_precision
def test_to_formatted_s__rounded__with_significant_true_and_zero_precision
# Zero precision with significant is a mistake (would always return zero),
# so we treat it as if significant was false (increases backwards compatibility for number_to_human_size)
assert_equal "124", 123.987.to_s(:rounded, precision: 0, significant: true)
assert_equal "12", 12.to_s(:rounded, precision: 0, significant: true)
assert_equal "124", 123.987.to_formatted_s(:rounded, precision: 0, significant: true)
assert_equal "12", 12.to_formatted_s(:rounded, precision: 0, significant: true)
end
def test_to_s__human_size
assert_equal "0 Bytes", 0.to_s(:human_size)
assert_equal "1 Byte", 1.to_s(:human_size)
assert_equal "3 Bytes", 3.14159265.to_s(:human_size)
assert_equal "123 Bytes", 123.0.to_s(:human_size)
assert_equal "123 Bytes", 123.to_s(:human_size)
assert_equal "1.21 KB", 1234.to_s(:human_size)
assert_equal "12.1 KB", 12345.to_s(:human_size)
assert_equal "1.18 MB", 1234567.to_s(:human_size)
assert_equal "1.15 GB", 1234567890.to_s(:human_size)
assert_equal "1.12 TB", 1234567890123.to_s(:human_size)
assert_equal "1.1 PB", 1234567890123456.to_s(:human_size)
assert_equal "1.07 EB", 1234567890123456789.to_s(:human_size)
assert_equal "1030 EB", exabytes(1026).to_s(:human_size)
assert_equal "444 KB", kilobytes(444).to_s(:human_size)
assert_equal "1020 MB", megabytes(1023).to_s(:human_size)
assert_equal "3 TB", terabytes(3).to_s(:human_size)
assert_equal "1.2 MB", 1234567.to_s(:human_size, precision: 2)
assert_equal "3 Bytes", 3.14159265.to_s(:human_size, precision: 4)
assert_equal "1 KB", kilobytes(1.0123).to_s(:human_size, precision: 2)
assert_equal "1.01 KB", kilobytes(1.0100).to_s(:human_size, precision: 4)
assert_equal "10 KB", kilobytes(10.000).to_s(:human_size, precision: 4)
assert_equal "1 Byte", 1.1.to_s(:human_size)
assert_equal "10 Bytes", 10.to_s(:human_size)
def test_to_formatted_s__percentage
assert_deprecated do
assert_equal("100.000%", 100.to_s(:percentage))
end
assert_equal("100.000%", 100.to_formatted_s(:percentage))
assert_equal("100%", 100.to_formatted_s(:percentage, precision: 0))
assert_equal("302.06%", 302.0574.to_formatted_s(:percentage, precision: 2))
assert_equal("302.05%", 302.0574.to_formatted_s(:percentage, precision: 2, round_mode: :down))
assert_equal("123.4%", 123.400.to_formatted_s(:percentage, precision: 3, strip_insignificant_zeros: true))
assert_equal("1.000,000%", 1000.to_formatted_s(:percentage, delimiter: ".", separator: ","))
assert_equal("1000.000 %", 1000.to_formatted_s(:percentage, format: "%n %"))
end
def test_to_s__human_size_with_options_hash
assert_equal "1.2 MB", 1234567.to_s(:human_size, precision: 2)
assert_equal "3 Bytes", 3.14159265.to_s(:human_size, precision: 4)
assert_equal "1 KB", kilobytes(1.0123).to_s(:human_size, precision: 2)
assert_equal "1.01 KB", kilobytes(1.0100).to_s(:human_size, precision: 4)
assert_equal "10 KB", kilobytes(10.000).to_s(:human_size, precision: 4)
assert_equal "1 TB", 1234567890123.to_s(:human_size, precision: 1)
assert_equal "500 MB", 524288000.to_s(:human_size, precision: 3)
assert_equal "10 MB", 9961472.to_s(:human_size, precision: 0)
assert_equal "40 KB", 41010.to_s(:human_size, precision: 1)
assert_equal "40 KB", 41100.to_s(:human_size, precision: 2)
assert_equal "50 KB", 41100.to_s(:human_size, precision: 1, round_mode: :up)
assert_equal "1.0 KB", kilobytes(1.0123).to_s(:human_size, precision: 2, strip_insignificant_zeros: false)
assert_equal "1.012 KB", kilobytes(1.0123).to_s(:human_size, precision: 3, significant: false)
assert_equal "1 KB", kilobytes(1.0123).to_s(:human_size, precision: 0, significant: true) # ignores significant it precision is 0
def test_to_formatted_s__delimited
assert_deprecated do
assert_equal("12,345,678", 12345678.to_s(:delimited))
end
assert_equal("12,345,678", 12345678.to_formatted_s(:delimited))
assert_equal("0", 0.to_formatted_s(:delimited))
assert_equal("123", 123.to_formatted_s(:delimited))
assert_equal("123,456", 123456.to_formatted_s(:delimited))
assert_equal("123,456.78", 123456.78.to_formatted_s(:delimited))
assert_equal("123,456.789", 123456.789.to_formatted_s(:delimited))
assert_equal("123,456.78901", 123456.78901.to_formatted_s(:delimited))
assert_equal("123,456,789.78901", 123456789.78901.to_formatted_s(:delimited))
assert_equal("0.78901", 0.78901.to_formatted_s(:delimited))
end
def test_to_s__human_size_with_custom_delimiter_and_separator
assert_equal "1,01 KB", kilobytes(1.0123).to_s(:human_size, precision: 3, separator: ",")
assert_equal "1,01 KB", kilobytes(1.0100).to_s(:human_size, precision: 4, separator: ",")
assert_equal "1.000,1 TB", terabytes(1000.1).to_s(:human_size, precision: 5, delimiter: ".", separator: ",")
def test_to_formatted_s__delimited__with_options_hash
assert_equal "12 345 678", 12345678.to_formatted_s(:delimited, delimiter: " ")
assert_equal "12,345,678-05", 12345678.05.to_formatted_s(:delimited, separator: "-")
assert_equal "12.345.678,05", 12345678.05.to_formatted_s(:delimited, separator: ",", delimiter: ".")
assert_equal "12.345.678,05", 12345678.05.to_formatted_s(:delimited, delimiter: ".", separator: ",")
end
def test_to_formatted_s__human_size
assert_deprecated do
assert_equal "0 Bytes", 0.to_s(:human_size)
end
assert_equal "0 Bytes", 0.to_formatted_s(:human_size)
assert_equal "1 Byte", 1.to_formatted_s(:human_size)
assert_equal "3 Bytes", 3.14159265.to_formatted_s(:human_size)
assert_equal "123 Bytes", 123.0.to_formatted_s(:human_size)
assert_equal "123 Bytes", 123.to_formatted_s(:human_size)
assert_equal "1.21 KB", 1234.to_formatted_s(:human_size)
assert_equal "12.1 KB", 12345.to_formatted_s(:human_size)
assert_equal "1.18 MB", 1234567.to_formatted_s(:human_size)
assert_equal "1.15 GB", 1234567890.to_formatted_s(:human_size)
assert_equal "1.12 TB", 1234567890123.to_formatted_s(:human_size)
assert_equal "1.1 PB", 1234567890123456.to_formatted_s(:human_size)
assert_equal "1.07 EB", 1234567890123456789.to_formatted_s(:human_size)
assert_equal "1030 EB", exabytes(1026).to_formatted_s(:human_size)
assert_equal "444 KB", kilobytes(444).to_formatted_s(:human_size)
assert_equal "1020 MB", megabytes(1023).to_formatted_s(:human_size)
assert_equal "3 TB", terabytes(3).to_formatted_s(:human_size)
assert_equal "1.2 MB", 1234567.to_formatted_s(:human_size, precision: 2)
assert_equal "3 Bytes", 3.14159265.to_formatted_s(:human_size, precision: 4)
assert_equal "1 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 2)
assert_equal "1.01 KB", kilobytes(1.0100).to_formatted_s(:human_size, precision: 4)
assert_equal "10 KB", kilobytes(10.000).to_formatted_s(:human_size, precision: 4)
assert_equal "1 Byte", 1.1.to_formatted_s(:human_size)
assert_equal "10 Bytes", 10.to_formatted_s(:human_size)
end
def test_to_formatted_s__human_size_with_options_hash
assert_equal "1.2 MB", 1234567.to_formatted_s(:human_size, precision: 2)
assert_equal "3 Bytes", 3.14159265.to_formatted_s(:human_size, precision: 4)
assert_equal "1 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 2)
assert_equal "1.01 KB", kilobytes(1.0100).to_formatted_s(:human_size, precision: 4)
assert_equal "10 KB", kilobytes(10.000).to_formatted_s(:human_size, precision: 4)
assert_equal "1 TB", 1234567890123.to_formatted_s(:human_size, precision: 1)
assert_equal "500 MB", 524288000.to_formatted_s(:human_size, precision: 3)
assert_equal "10 MB", 9961472.to_formatted_s(:human_size, precision: 0)
assert_equal "40 KB", 41010.to_formatted_s(:human_size, precision: 1)
assert_equal "40 KB", 41100.to_formatted_s(:human_size, precision: 2)
assert_equal "50 KB", 41100.to_formatted_s(:human_size, precision: 1, round_mode: :up)
assert_equal "1.0 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 2, strip_insignificant_zeros: false)
assert_equal "1.012 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 3, significant: false)
assert_equal "1 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 0, significant: true) # ignores significant it precision is 0
end
def test_to_formatted_s__human_size_with_custom_delimiter_and_separator
assert_equal "1,01 KB", kilobytes(1.0123).to_formatted_s(:human_size, precision: 3, separator: ",")
assert_equal "1,01 KB", kilobytes(1.0100).to_formatted_s(:human_size, precision: 4, separator: ",")
assert_equal "1.000,1 TB", terabytes(1000.1).to_formatted_s(:human_size, precision: 5, delimiter: ".", separator: ",")
end
def test_number_to_human
assert_equal "-123", -123.to_s(:human)
assert_equal "-0.5", -0.5.to_s(:human)
assert_equal "0", 0.to_s(:human)
assert_equal "0.5", 0.5.to_s(:human)
assert_equal "123", 123.to_s(:human)
assert_equal "1.23 Thousand", 1234.to_s(:human)
assert_equal "12.3 Thousand", 12345.to_s(:human)
assert_equal "1.23 Million", 1234567.to_s(:human)
assert_equal "1.23 Billion", 1234567890.to_s(:human)
assert_equal "1.23 Trillion", 1234567890123.to_s(:human)
assert_equal "1.23 Quadrillion", 1234567890123456.to_s(:human)
assert_equal "1230 Quadrillion", 1234567890123456789.to_s(:human)
assert_equal "490 Thousand", 489939.to_s(:human, precision: 2)
assert_equal "489.9 Thousand", 489939.to_s(:human, precision: 4)
assert_equal "489 Thousand", 489000.to_s(:human, precision: 4)
assert_equal "480 Thousand", 489939.to_s(:human, precision: 2, round_mode: :down)
assert_equal "489.0 Thousand", 489000.to_s(:human, precision: 4, strip_insignificant_zeros: false)
assert_equal "1.2346 Million", 1234567.to_s(:human, precision: 4, significant: false)
assert_equal "1,2 Million", 1234567.to_s(:human, precision: 1, significant: false, separator: ",")
assert_equal "1 Million", 1234567.to_s(:human, precision: 0, significant: true, separator: ",") # significant forced to false
assert_deprecated do
assert_equal "-123", -123.to_s(:human)
end
assert_equal "-123", -123.to_formatted_s(:human)
assert_equal "-0.5", -0.5.to_formatted_s(:human)
assert_equal "0", 0.to_formatted_s(:human)
assert_equal "0.5", 0.5.to_formatted_s(:human)
assert_equal "123", 123.to_formatted_s(:human)
assert_equal "1.23 Thousand", 1234.to_formatted_s(:human)
assert_equal "12.3 Thousand", 12345.to_formatted_s(:human)
assert_equal "1.23 Million", 1234567.to_formatted_s(:human)
assert_equal "1.23 Billion", 1234567890.to_formatted_s(:human)
assert_equal "1.23 Trillion", 1234567890123.to_formatted_s(:human)
assert_equal "1.23 Quadrillion", 1234567890123456.to_formatted_s(:human)
assert_equal "1230 Quadrillion", 1234567890123456789.to_formatted_s(:human)
assert_equal "490 Thousand", 489939.to_formatted_s(:human, precision: 2)
assert_equal "489.9 Thousand", 489939.to_formatted_s(:human, precision: 4)
assert_equal "489 Thousand", 489000.to_formatted_s(:human, precision: 4)
assert_equal "480 Thousand", 489939.to_formatted_s(:human, precision: 2, round_mode: :down)
assert_equal "489.0 Thousand", 489000.to_formatted_s(:human, precision: 4, strip_insignificant_zeros: false)
assert_equal "1.2346 Million", 1234567.to_formatted_s(:human, precision: 4, significant: false)
assert_equal "1,2 Million", 1234567.to_formatted_s(:human, precision: 1, significant: false, separator: ",")
assert_equal "1 Million", 1234567.to_formatted_s(:human, precision: 0, significant: true, separator: ",") # significant forced to false
end
def test_number_to_human_with_custom_units
# Only integers
volume = { unit: "ml", thousand: "lt", million: "m3" }
assert_equal "123 lt", 123456.to_s(:human, units: volume)
assert_equal "12 ml", 12.to_s(:human, units: volume)
assert_equal "1.23 m3", 1234567.to_s(:human, units: volume)
assert_equal "123 lt", 123456.to_formatted_s(:human, units: volume)
assert_equal "12 ml", 12.to_formatted_s(:human, units: volume)
assert_equal "1.23 m3", 1234567.to_formatted_s(:human, units: volume)
# Including fractionals
distance = { mili: "mm", centi: "cm", deci: "dm", unit: "m", ten: "dam", hundred: "hm", thousand: "km" }
assert_equal "1.23 mm", 0.00123.to_s(:human, units: distance)
assert_equal "1.23 cm", 0.0123.to_s(:human, units: distance)
assert_equal "1.23 dm", 0.123.to_s(:human, units: distance)
assert_equal "1.23 m", 1.23.to_s(:human, units: distance)
assert_equal "1.23 dam", 12.3.to_s(:human, units: distance)
assert_equal "1.23 hm", 123.to_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_s(:human, units: distance)
assert_equal "12.3 km", 12300.to_s(:human, units: distance)
assert_equal "1.23 mm", 0.00123.to_formatted_s(:human, units: distance)
assert_equal "1.23 cm", 0.0123.to_formatted_s(:human, units: distance)
assert_equal "1.23 dm", 0.123.to_formatted_s(:human, units: distance)
assert_equal "1.23 m", 1.23.to_formatted_s(:human, units: distance)
assert_equal "1.23 dam", 12.3.to_formatted_s(:human, units: distance)
assert_equal "1.23 hm", 123.to_formatted_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_formatted_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_formatted_s(:human, units: distance)
assert_equal "1.23 km", 1230.to_formatted_s(:human, units: distance)
assert_equal "12.3 km", 12300.to_formatted_s(:human, units: distance)
# The quantifiers don't need to be a continuous sequence
gangster = { hundred: "hundred bucks", million: "thousand quids" }
assert_equal "1 hundred bucks", 100.to_s(:human, units: gangster)
assert_equal "25 hundred bucks", 2500.to_s(:human, units: gangster)
assert_equal "25 thousand quids", 25000000.to_s(:human, units: gangster)
assert_equal "12300 thousand quids", 12345000000.to_s(:human, units: gangster)
assert_equal "1 hundred bucks", 100.to_formatted_s(:human, units: gangster)
assert_equal "25 hundred bucks", 2500.to_formatted_s(:human, units: gangster)
assert_equal "25 thousand quids", 25000000.to_formatted_s(:human, units: gangster)
assert_equal "12300 thousand quids", 12345000000.to_formatted_s(:human, units: gangster)
# Spaces are stripped from the resulting string
assert_equal "4", 4.to_s(:human, units: { unit: "", ten: "tens " })
assert_equal "4.5 tens", 45.to_s(:human, units: { unit: "", ten: " tens " })
assert_equal "4", 4.to_formatted_s(:human, units: { unit: "", ten: "tens " })
assert_equal "4.5 tens", 45.to_formatted_s(:human, units: { unit: "", ten: " tens " })
end
def test_number_to_human_with_custom_format
assert_equal "123 times Thousand", 123456.to_s(:human, format: "%n times %u")
assert_equal "123 times Thousand", 123456.to_formatted_s(:human, format: "%n times %u")
volume = { unit: "ml", thousand: "lt", million: "m3" }
assert_equal "123.lt", 123456.to_s(:human, units: volume, format: "%n.%u")
assert_equal "123.lt", 123456.to_formatted_s(:human, units: volume, format: "%n.%u")
end
def test_to_s__injected_on_proper_types
assert_equal "1.23 Thousand", 1230.to_s(:human)
assert_equal "1.23 Thousand", Float(1230).to_s(:human)
assert_equal "100000 Quadrillion", (100**10).to_s(:human)
assert_equal "1 Million", BigDecimal("1000010").to_s(:human)
def test_to_formatted_s__injected_on_proper_types
assert_equal "1.23 Thousand", 1230.to_formatted_s(:human)
assert_equal "1.23 Thousand", Float(1230).to_formatted_s(:human)
assert_equal "100000 Quadrillion", (100**10).to_formatted_s(:human)
assert_equal "1 Million", BigDecimal("1000010").to_formatted_s(:human)
end
def test_to_s_with_invalid_formatter
assert_equal "123", 123.to_s(:invalid)
assert_equal "2.5", 2.5.to_s(:invalid)
assert_equal "100000000000000000000", (100**10).to_s(:invalid)
assert_equal "1000010.0", BigDecimal("1000010").to_s(:invalid)
def test_to_formatted_s_with_invalid_formatter
assert_deprecated do
assert_equal "123", 123.to_s(:invalid)
end
assert_equal "123", 123.to_formatted_s(:invalid)
assert_equal "2.5", 2.5.to_formatted_s(:invalid)
assert_equal "100000000000000000000", (100**10).to_formatted_s(:invalid)
assert_equal "1000010.0", BigDecimal("1000010").to_formatted_s(:invalid)
end
def test_default_to_s
def test_default_to_formatted_s
assert_equal "123", 123.to_s
assert_equal "123", 123.to_formatted_s
assert_equal "1111011", 123.to_s(2)
assert_equal "1111011", 123.to_formatted_s(2)
assert_equal "2.5", 2.5.to_s
assert_equal "2.5", 2.5.to_formatted_s
assert_equal "100000000000000000000", (100**10).to_s
assert_equal "100000000000000000000", (100**10).to_formatted_s
assert_equal "1010110101111000111010111100010110101100011000100000000000000000000", (100**10).to_s(2)
assert_equal "1010110101111000111010111100010110101100011000100000000000000000000", (100**10).to_formatted_s(2)
assert_equal "1000010.0", BigDecimal("1000010").to_s
assert_equal "1000010.0", BigDecimal("1000010").to_formatted_s
assert_equal "10000 10.0", BigDecimal("1000010").to_s("5F")
assert_equal "10000 10.0", BigDecimal("1000010").to_formatted_s("5F")
assert_raises TypeError do
1.to_s({})
end
end
def test_in_milliseconds
assert_equal 10_000, 10.seconds.in_milliseconds
assert_raises TypeError do
1.to_formatted_s({})
end
end
end

View File

@ -6,26 +6,42 @@ require "active_support/core_ext/numeric"
require "active_support/core_ext/range"
class RangeTest < ActiveSupport::TestCase
def test_to_s_from_dates
def test_to_formatted_s_from_dates
date_range = Date.new(2005, 12, 10)..Date.new(2005, 12, 12)
assert_equal "BETWEEN '2005-12-10' AND '2005-12-12'", date_range.to_formatted_s(:db)
end
def test_to_s_from_times
def test_to_formatted_s_from_times
date_range = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30)
assert_equal "BETWEEN '2005-12-10 15:30:00' AND '2005-12-10 17:30:00'", date_range.to_formatted_s(:db)
end
def test_to_s_with_alphabets
def test_to_formatted_s_with_alphabets
alphabet_range = ("a".."z")
assert_equal "BETWEEN 'a' AND 'z'", alphabet_range.to_formatted_s(:db)
end
def test_to_s_with_numeric
def test_to_formatted_s_with_numeric
number_range = (1..100)
assert_equal "BETWEEN '1' AND '100'", number_range.to_formatted_s(:db)
end
def test_to_s_with_format
number_range = (1..100)
assert_deprecated do
assert_equal "BETWEEN '1' AND '100'", number_range.to_s(:db)
end
end
def test_to_s_with_format_invalid_format
number_range = (1..100)
assert_deprecated do
assert_equal "1..100", number_range.to_s(:not_existent)
end
end
def test_date_range
assert_instance_of Range, DateTime.new..DateTime.new
assert_instance_of Range, DateTime::Infinity.new..DateTime::Infinity.new

View File

@ -582,33 +582,105 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
def test_to_s
time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901)
assert_equal time.to_default_s, time.to_s
assert_equal time.to_default_s, time.to_s(:doesnt_exist)
assert_equal "2005-02-21 17:44:30", time.to_formatted_s(:db)
assert_equal "21 Feb 17:44", time.to_s(:short)
assert_equal "17:44", time.to_s(:time)
assert_equal "20050221174430", time.to_s(:number)
assert_equal "20050221174430123456789", time.to_s(:nsec)
assert_equal "20050221174430123456", time.to_s(:usec)
assert_equal "February 21, 2005 17:44", time.to_s(:long)
assert_equal "February 21st, 2005 17:44", time.to_s(:long_ordinal)
assert_deprecated do
assert_equal time.to_default_s, time.to_s(:doesnt_exist)
end
assert_deprecated do
assert_equal "2005-02-21 17:44:30", time.to_s(:db)
end
assert_deprecated do
assert_equal "21 Feb 17:44", time.to_s(:short)
end
assert_deprecated do
assert_equal "17:44", time.to_s(:time)
end
assert_deprecated do
assert_equal "20050221174430", time.to_s(:number)
end
assert_deprecated do
assert_equal "20050221174430123456789", time.to_s(:nsec)
end
assert_deprecated do
assert_equal "20050221174430123456", time.to_s(:usec)
end
assert_deprecated do
assert_equal "February 21, 2005 17:44", time.to_s(:long)
end
assert_deprecated do
assert_equal "February 21st, 2005 17:44", time.to_s(:long_ordinal)
end
with_env_tz "UTC" do
assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_s(:rfc822)
assert_equal "2005-02-21 17:44:30.123456789 +0000", time.to_s(:inspect)
assert_deprecated do
assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_s(:rfc822)
end
assert_deprecated do
assert_equal "2005-02-21 17:44:30.123456789 +0000", time.to_s(:inspect)
end
end
with_env_tz "US/Central" do
assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822)
assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822)
assert_equal "2009-02-05T14:30:05-06:00", Time.local(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
assert_equal "2008-06-09T04:05:01-05:00", Time.local(2008, 6, 9, 4, 5, 1).to_s(:iso8601)
assert_equal "2009-02-05T14:30:05Z", Time.utc(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
assert_equal "2009-02-05 14:30:05.000000000 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:inspect)
assert_equal "2008-06-09 04:05:01.000000000 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:inspect)
assert_deprecated do
assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:rfc822)
end
assert_deprecated do
assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:rfc822)
end
assert_deprecated do
assert_equal "2009-02-05T14:30:05-06:00", Time.local(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
end
assert_deprecated do
assert_equal "2008-06-09T04:05:01-05:00", Time.local(2008, 6, 9, 4, 5, 1).to_s(:iso8601)
end
assert_deprecated do
assert_equal "2009-02-05T14:30:05Z", Time.utc(2009, 2, 5, 14, 30, 5).to_s(:iso8601)
end
assert_deprecated do
assert_equal "2009-02-05 14:30:05.000000000 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_s(:inspect)
end
assert_deprecated do
assert_equal "2008-06-09 04:05:01.000000000 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_s(:inspect)
end
end
end
def test_custom_date_format
def test_to_formatted_s
time = Time.utc(2005, 2, 21, 17, 44, 30.12345678901)
assert_equal time.to_s, time.to_formatted_s(:doesnt_exist)
assert_equal "2005-02-21 17:44:30", time.to_formatted_s(:db)
assert_equal "21 Feb 17:44", time.to_formatted_s(:short)
assert_equal "17:44", time.to_formatted_s(:time)
assert_equal "20050221174430", time.to_formatted_s(:number)
assert_equal "20050221174430123456789", time.to_formatted_s(:nsec)
assert_equal "20050221174430123456", time.to_formatted_s(:usec)
assert_equal "February 21, 2005 17:44", time.to_formatted_s(:long)
assert_equal "February 21st, 2005 17:44", time.to_formatted_s(:long_ordinal)
with_env_tz "UTC" do
assert_equal "Mon, 21 Feb 2005 17:44:30 +0000", time.to_formatted_s(:rfc822)
assert_equal "2005-02-21 17:44:30.123456789 +0000", time.to_formatted_s(:inspect)
end
with_env_tz "US/Central" do
assert_equal "Thu, 05 Feb 2009 14:30:05 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_formatted_s(:rfc822)
assert_equal "Mon, 09 Jun 2008 04:05:01 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_formatted_s(:rfc822)
assert_equal "2009-02-05T14:30:05-06:00", Time.local(2009, 2, 5, 14, 30, 5).to_formatted_s(:iso8601)
assert_equal "2008-06-09T04:05:01-05:00", Time.local(2008, 6, 9, 4, 5, 1).to_formatted_s(:iso8601)
assert_equal "2009-02-05T14:30:05Z", Time.utc(2009, 2, 5, 14, 30, 5).to_formatted_s(:iso8601)
assert_equal "2009-02-05 14:30:05.000000000 -0600", Time.local(2009, 2, 5, 14, 30, 5).to_formatted_s(:inspect)
assert_equal "2008-06-09 04:05:01.000000000 -0500", Time.local(2008, 6, 9, 4, 5, 1).to_formatted_s(:inspect)
end
end
def test_to_s_custom_date_format
Time::DATE_FORMATS[:custom] = "%Y%m%d%H%M%S"
assert_equal "20050221143000", Time.local(2005, 2, 21, 14, 30, 0).to_s(:custom)
assert_deprecated do
assert_equal "20050221143000", Time.local(2005, 2, 21, 14, 30, 0).to_s(:custom)
end
ensure
Time::DATE_FORMATS.delete(:custom)
end
def test_to_formatted_s_custom_date_format
Time::DATE_FORMATS[:custom] = "%Y%m%d%H%M%S"
assert_equal "20050221143000", Time.local(2005, 2, 21, 14, 30, 0).to_formatted_s(:custom)
ensure
Time::DATE_FORMATS.delete(:custom)
end

View File

@ -137,12 +137,30 @@ class TimeWithZoneTest < ActiveSupport::TestCase
assert_equal "1999-12-31 19:00:00 -0500", @twz.to_formatted_s
end
def test_to_s_db
def test_to_formatted_s_db
assert_equal "2000-01-01 00:00:00", @twz.to_formatted_s(:db)
end
def test_to_formatted_s_inspect
assert_equal "1999-12-31 19:00:00.000000000 -0500", @twz.to_formatted_s(:inspect)
end
def test_to_s_db
assert_deprecated do
assert_equal "2000-01-01 00:00:00", @twz.to_s(:db)
end
end
def test_to_s_inspect
assert_equal "1999-12-31 19:00:00.000000000 -0500", @twz.to_s(:inspect)
assert_deprecated do
assert_equal "1999-12-31 19:00:00.000000000 -0500", @twz.to_s(:inspect)
end
end
def test_to_s_not_existent
assert_deprecated do
assert_equal "1999-12-31 19:00:00 -0500", @twz.to_s(:not_existent)
end
end
def test_xmlschema

View File

@ -1988,84 +1988,84 @@ Enables the formatting of numbers in a variety of ways.
Produce a string representation of a number as a telephone number:
```ruby
5551234.to_s(:phone)
5551234.to_formatted_s(:phone)
# => 555-1234
1235551234.to_s(:phone)
1235551234.to_formatted_s(:phone)
# => 123-555-1234
1235551234.to_s(:phone, area_code: true)
1235551234.to_formatted_s(:phone, area_code: true)
# => (123) 555-1234
1235551234.to_s(:phone, delimiter: " ")
1235551234.to_formatted_s(:phone, delimiter: " ")
# => 123 555 1234
1235551234.to_s(:phone, area_code: true, extension: 555)
1235551234.to_formatted_s(:phone, area_code: true, extension: 555)
# => (123) 555-1234 x 555
1235551234.to_s(:phone, country_code: 1)
1235551234.to_formatted_s(:phone, country_code: 1)
# => +1-123-555-1234
```
Produce a string representation of a number as currency:
```ruby
1234567890.50.to_s(:currency) # => $1,234,567,890.50
1234567890.506.to_s(:currency) # => $1,234,567,890.51
1234567890.506.to_s(:currency, precision: 3) # => $1,234,567,890.506
1234567890.50.to_formatted_s(:currency) # => $1,234,567,890.50
1234567890.506.to_formatted_s(:currency) # => $1,234,567,890.51
1234567890.506.to_formatted_s(:currency, precision: 3) # => $1,234,567,890.506
```
Produce a string representation of a number as a percentage:
```ruby
100.to_s(:percentage)
100.to_formatted_s(:percentage)
# => 100.000%
100.to_s(:percentage, precision: 0)
100.to_formatted_s(:percentage, precision: 0)
# => 100%
1000.to_s(:percentage, delimiter: '.', separator: ',')
1000.to_formatted_s(:percentage, delimiter: '.', separator: ',')
# => 1.000,000%
302.24398923423.to_s(:percentage, precision: 5)
302.24398923423.to_formatted_s(:percentage, precision: 5)
# => 302.24399%
```
Produce a string representation of a number in delimited form:
```ruby
12345678.to_s(:delimited) # => 12,345,678
12345678.05.to_s(:delimited) # => 12,345,678.05
12345678.to_s(:delimited, delimiter: ".") # => 12.345.678
12345678.to_s(:delimited, delimiter: ",") # => 12,345,678
12345678.05.to_s(:delimited, separator: " ") # => 12,345,678 05
12345678.to_formatted_s(:delimited) # => 12,345,678
12345678.05.to_formatted_s(:delimited) # => 12,345,678.05
12345678.to_formatted_s(:delimited, delimiter: ".") # => 12.345.678
12345678.to_formatted_s(:delimited, delimiter: ",") # => 12,345,678
12345678.05.to_formatted_s(:delimited, separator: " ") # => 12,345,678 05
```
Produce a string representation of a number rounded to a precision:
```ruby
111.2345.to_s(:rounded) # => 111.235
111.2345.to_s(:rounded, precision: 2) # => 111.23
13.to_s(:rounded, precision: 5) # => 13.00000
389.32314.to_s(:rounded, precision: 0) # => 389
111.2345.to_s(:rounded, significant: true) # => 111
111.2345.to_formatted_s(:rounded) # => 111.235
111.2345.to_formatted_s(:rounded, precision: 2) # => 111.23
13.to_formatted_s(:rounded, precision: 5) # => 13.00000
389.32314.to_formatted_s(:rounded, precision: 0) # => 389
111.2345.to_formatted_s(:rounded, significant: true) # => 111
```
Produce a string representation of a number as a human-readable number of bytes:
```ruby
123.to_s(:human_size) # => 123 Bytes
1234.to_s(:human_size) # => 1.21 KB
12345.to_s(:human_size) # => 12.1 KB
1234567.to_s(:human_size) # => 1.18 MB
1234567890.to_s(:human_size) # => 1.15 GB
1234567890123.to_s(:human_size) # => 1.12 TB
1234567890123456.to_s(:human_size) # => 1.1 PB
1234567890123456789.to_s(:human_size) # => 1.07 EB
123.to_formatted_s(:human_size) # => 123 Bytes
1234.to_formatted_s(:human_size) # => 1.21 KB
12345.to_formatted_s(:human_size) # => 12.1 KB
1234567.to_formatted_s(:human_size) # => 1.18 MB
1234567890.to_formatted_s(:human_size) # => 1.15 GB
1234567890123.to_formatted_s(:human_size) # => 1.12 TB
1234567890123456.to_formatted_s(:human_size) # => 1.1 PB
1234567890123456789.to_formatted_s(:human_size) # => 1.07 EB
```
Produce a string representation of a number in human-readable words:
```ruby
123.to_s(:human) # => "123"
1234.to_s(:human) # => "1.23 Thousand"
12345.to_s(:human) # => "12.3 Thousand"
1234567.to_s(:human) # => "1.23 Million"
1234567890.to_s(:human) # => "1.23 Billion"
1234567890123.to_s(:human) # => "1.23 Trillion"
1234567890123456.to_s(:human) # => "1.23 Quadrillion"
123.to_formatted_s(:human) # => "123"
1234.to_formatted_s(:human) # => "1.23 Thousand"
12345.to_formatted_s(:human) # => "12.3 Thousand"
1234567.to_formatted_s(:human) # => "1.23 Million"
1234567890.to_formatted_s(:human) # => "1.23 Billion"
1234567890123.to_formatted_s(:human) # => "1.23 Trillion"
1234567890123456.to_formatted_s(:human) # => "1.23 Quadrillion"
```
NOTE: Defined in `active_support/core_ext/numeric/conversions.rb`.
@ -2160,12 +2160,6 @@ The method `to_s` provides a default specifier of "F". This means that a simple
BigDecimal(5.00, 6).to_s # => "5.0"
```
and that symbol specifiers are also supported:
```ruby
BigDecimal(5.00, 6).to_s(:db) # => "5.0"
```
Engineering notation is still supported:
```ruby