aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md78
-rw-r--r--activesupport/activesupport.gemspec2
-rw-r--r--activesupport/lib/active_support/backtrace_cleaner.rb2
-rw-r--r--activesupport/lib/active_support/cache.rb2
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb46
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb2
-rw-r--r--activesupport/lib/active_support/callbacks.rb10
-rw-r--r--activesupport/lib/active_support/configurable.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/class/delegating_attributes.rb17
-rw-r--r--activesupport/lib/active_support/core_ext/hash/except.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/hash/keys.rb12
-rw-r--r--activesupport/lib/active_support/core_ext/module.rb1
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/concerning.rb135
-rw-r--r--activesupport/lib/active_support/core_ext/string/output_safety.rb19
-rw-r--r--activesupport/lib/active_support/core_ext/thread.rb2
-rw-r--r--activesupport/lib/active_support/i18n_railtie.rb14
-rw-r--r--activesupport/lib/active_support/json/encoding.rb43
-rw-r--r--activesupport/lib/active_support/message_verifier.rb5
-rw-r--r--activesupport/lib/active_support/number_helper.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_phone_converter.rb2
-rw-r--r--activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb44
-rw-r--r--activesupport/lib/active_support/per_thread_registry.rb7
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb4
-rw-r--r--activesupport/lib/active_support/version.rb2
-rw-r--r--activesupport/test/abstract_unit.rb4
-rw-r--r--activesupport/test/callbacks_test.rb21
-rw-r--r--activesupport/test/configurable_test.rb14
-rw-r--r--activesupport/test/core_ext/blank_test.rb8
-rw-r--r--activesupport/test/core_ext/class/delegating_attributes_test.rb5
-rw-r--r--activesupport/test/core_ext/duration_test.rb8
-rw-r--r--activesupport/test/core_ext/module/concerning_test.rb35
-rw-r--r--activesupport/test/core_ext/module_test.rb6
-rw-r--r--activesupport/test/core_ext/name_error_test.rb12
-rw-r--r--activesupport/test/core_ext/object_and_class_ext_test.rb25
-rw-r--r--activesupport/test/dependencies_test.rb48
-rw-r--r--activesupport/test/deprecation_test.rb11
-rw-r--r--activesupport/test/empty_bool.rb7
-rw-r--r--activesupport/test/fixtures/custom.rb2
-rw-r--r--activesupport/test/message_verifier_test.rb14
-rw-r--r--activesupport/test/multibyte_chars_test.rb6
-rw-r--r--activesupport/test/number_helper_test.rb14
-rw-r--r--activesupport/test/safe_buffer_test.rb25
-rw-r--r--activesupport/test/test_test.rb8
-rw-r--r--activesupport/test/testing/constant_lookup_test.rb1
46 files changed, 504 insertions, 231 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index d23b598144..3379460fa2 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,11 +1,77 @@
-* Fix file descriptor being leaked on each call to `Kernel.silence_stream`
+* Fixed Float related error in NumberHelper with large precisions.
- *Mario Visic*
+ before:
+ ActiveSupport::NumberHelper.number_to_rounded '3.14159', precision: 50
+ #=> "3.14158999999999988261834005243144929409027099609375"
+ after:
+ ActiveSupport::NumberHelper.number_to_rounded '3.14159', precision: 50
+ #=> "3.14159000000000000000000000000000000000000000000000"
-* Ensure `config.i18n.enforce_available_locales` is set before any other
- configuration option.
+ *Kenta Murata*, *Akira Matsuda*
- *Yves Senn*
+* Default the new `I18n.enforce_available_locales` config to `true`, meaning
+ `I18n` will make sure that all locales passed to it must be declared in the
+ `available_locales` list.
+
+ To disable it add the following configuration to your application:
+
+ config.i18n.enforce_available_locales = false
+
+ This also ensures I18n configuration is properly initialized taking the new
+ option into account, to avoid their deprecations while booting up the app.
+
+ *Carlos Antonio da Silva*, *Yves Senn*
+
+* Introduce Module#concerning: a natural, low-ceremony way to separate
+ responsibilities within a class.
+
+ Imported from https://github.com/37signals/concerning#readme
+
+ class Todo < ActiveRecord::Base
+ concerning :EventTracking do
+ included do
+ has_many :events
+ end
+
+ def latest_event
+ ...
+ end
+
+ private
+ def some_internal_method
+ ...
+ end
+ end
+
+ concerning :Trashable do
+ def trashed?
+ ...
+ end
+
+ def latest_event
+ super some_option: true
+ end
+ end
+ end
+
+ is equivalent to defining these modules inline, extending them into
+ concerns, then mixing them in to the class.
+
+ Inline concerns tame "junk drawer" classes that intersperse many unrelated
+ class-level declarations, public instance methods, and private
+ implementation. Coalesce related bits and give them definition.
+ These are a stepping stone toward future growth & refactoring.
+
+ When to move on from an inline concern:
+ * Encapsulating state? Extract collaborator object.
+ * Encompassing more public behavior or implementation? Move to separate file.
+ * Sharing behavior among classes? Move to separate file.
+
+ *Jeremy Kemper*
+
+* Fix file descriptor being leaked on each call to `Kernel.silence_stream`.
+
+ *Mario Visic*
* Added `Date#all_week/month/quarter/year` for generating date ranges.
@@ -292,7 +358,7 @@
*Arun Agrawal*
-* Remove deprecated `DateTime.local_offset` in favor of `DateTime.civil_from_fromat`.
+* Remove deprecated `DateTime.local_offset` in favor of `DateTime.civil_from_format`.
*Arun Agrawal*
diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec
index 0427022dc6..f3625e8b79 100644
--- a/activesupport/activesupport.gemspec
+++ b/activesupport/activesupport.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.rdoc_options.concat ['--encoding', 'UTF-8']
- s.add_dependency 'i18n', '~> 0.6', '>= 0.6.4'
+ s.add_dependency 'i18n', '~> 0.6', '>= 0.6.9'
s.add_dependency 'json', '~> 1.7', '>= 1.7.7'
s.add_dependency 'tzinfo', '~> 1.1'
s.add_dependency 'minitest', '~> 5.1'
diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb
index c88ae3e661..d58578b7bc 100644
--- a/activesupport/lib/active_support/backtrace_cleaner.rb
+++ b/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -22,7 +22,7 @@ module ActiveSupport
# <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
# backtrace to a pristine state. If you need to reconfigure an existing
# BacktraceCleaner so that it does not filter or modify the paths of any lines
- # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!<tt>
+ # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
# These two methods will give you a completely untouched backtrace.
#
# Inspired by the Quiet Backtrace gem by Thoughtbot.
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index d584d50da8..53154aef27 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -401,7 +401,7 @@ module ActiveSupport
end
end
- # Return +true+ if the cache contains an entry for the given key.
+ # Returns +true+ if the cache contains an entry for the given key.
#
# Options are passed to the underlying cache implementation.
def exist?(name, options = nil)
diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb
index 5cd6065077..8ed60aebac 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -22,15 +22,15 @@ module ActiveSupport
extend Strategy::LocalCache
end
- # Deletes all items from the cache. In this case it deletes all the entries in the specified
- # file store directory except for .gitkeep. Be careful which directory is specified in your
+ # Deletes all items from the cache. In this case it deletes all the entries in the specified
+ # file store directory except for .gitkeep. Be careful which directory is specified in your
# config file when using +FileStore+ because everything in that directory will be deleted.
def clear(options = nil)
root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)}
FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
end
- # Premptively iterates through all stored keys and removes the ones which have expired.
+ # Preemptively iterates through all stored keys and removes the ones which have expired.
def cleanup(options = nil)
options = merged_options(options)
search_dir(cache_path) do |fname|
@@ -43,33 +43,13 @@ module ActiveSupport
# Increments an already existing integer value that is stored in the cache.
# If the key is not found nothing is done.
def increment(name, amount = 1, options = nil)
- file_name = key_file_path(namespaced_key(name, options))
- lock_file(file_name) do
- options = merged_options(options)
- if num = read(name, options)
- num = num.to_i + amount
- write(name, num, options)
- num
- else
- nil
- end
- end
+ modify_value(name, amount, options)
end
# Decrements an already existing integer value that is stored in the cache.
# If the key is not found nothing is done.
def decrement(name, amount = 1, options = nil)
- file_name = key_file_path(namespaced_key(name, options))
- lock_file(file_name) do
- options = merged_options(options)
- if num = read(name, options)
- num = num.to_i - amount
- write(name, num, options)
- num
- else
- nil
- end
- end
+ modify_value(name, -amount, options)
end
def delete_matched(matcher, options = nil)
@@ -184,6 +164,22 @@ module ActiveSupport
end
end
end
+
+ # Modifies the amount of an already existing integer value that is stored in the cache.
+ # If the key is not found nothing is done.
+ def modify_value(name, amount, options)
+ file_name = key_file_path(namespaced_key(name, options))
+
+ lock_file(file_name) do
+ options = merged_options(options)
+
+ if num = read(name, options)
+ num = num.to_i + amount
+ write(name, num, options)
+ num
+ end
+ end
+ end
end
end
end
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index 34ac91334a..8a0523d0e2 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -36,7 +36,7 @@ module ActiveSupport
end
end
- # Premptively iterates through all stored keys and removes the ones which have expired.
+ # Preemptively iterates through all stored keys and removes the ones which have expired.
def cleanup(options = nil)
options = merged_options(options)
instrument(:cleanup, :size => @data.size) do
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index c3aac31323..e14ece7f35 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -7,14 +7,14 @@ require 'active_support/core_ext/kernel/singleton_class'
require 'thread'
module ActiveSupport
- # Callbacks are code hooks that are run at key points in an object's lifecycle.
+ # Callbacks are code hooks that are run at key points in an object's life cycle.
# The typical use case is to have a base class define a set of callbacks
# relevant to the other functionality it supplies, so that subclasses can
# install callbacks that enhance or modify the base functionality without
# needing to override or redefine methods of the base class.
#
# Mixing in this module allows you to define the events in the object's
- # lifecycle that will support callbacks (via +ClassMethods.define_callbacks+),
+ # life cycle that will support callbacks (via +ClassMethods.define_callbacks+),
# set the instance methods, procs, or callback objects to be called (via
# +ClassMethods.set_callback+), and run the installed callbacks at the
# appropriate times (via +run_callbacks+).
@@ -89,7 +89,7 @@ module ActiveSupport
private
- # A hook invoked everytime a before callback is halted.
+ # A hook invoked every time a before callback is halted.
# This can be overridden in AS::Callback implementors in order
# to provide better debugging/logging.
def halted_callback_hook(filter)
@@ -577,7 +577,7 @@ module ActiveSupport
# The callback can be specified as a symbol naming an instance method; as a
# proc, lambda, or block; as a string to be instance evaluated; or as an
# object that responds to a certain method determined by the <tt>:scope</tt>
- # argument to +define_callback+.
+ # argument to +define_callbacks+.
#
# If a proc, lambda, or block is given, its body is evaluated in the context
# of the current object. It can also optionally accept the current object as
@@ -648,7 +648,7 @@ module ActiveSupport
self.set_callbacks name, callbacks.dup.clear
end
- # Define sets of events in the object lifecycle that support callbacks.
+ # Define sets of events in the object life cycle that support callbacks.
#
# define_callbacks :validate
# define_callbacks :initialize, :save, :destroy
diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb
index e0d39d509f..3dd44e32d8 100644
--- a/activesupport/lib/active_support/configurable.rb
+++ b/activesupport/lib/active_support/configurable.rb
@@ -107,7 +107,7 @@ module ActiveSupport
options = names.extract_options!
names.each do |name|
- raise NameError.new('invalid config attribute name') unless name =~ /^[_A-Za-z]\w*$/
+ raise NameError.new('invalid config attribute name') unless name =~ /\A[_A-Za-z]\w*\z/
reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
diff --git a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
index ff870f5fd1..c2219beb5a 100644
--- a/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
+++ b/activesupport/lib/active_support/core_ext/class/delegating_attributes.rb
@@ -4,20 +4,21 @@ require 'active_support/core_ext/module/remove_method'
class Class
def superclass_delegating_accessor(name, options = {})
# Create private _name and _name= methods that can still be used if the public
- # methods are overridden. This allows
- _superclass_delegating_accessor("_#{name}")
+ # methods are overridden.
+ _superclass_delegating_accessor("_#{name}", options)
- # Generate the public methods name, name=, and name?
+ # Generate the public methods name, name=, and name?.
# These methods dispatch to the private _name, and _name= methods, making them
- # overridable
+ # overridable.
singleton_class.send(:define_method, name) { send("_#{name}") }
singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") }
singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) }
- # If an instance_reader is needed, generate methods for name and name= on the
- # class itself, so instances will be able to see them
- define_method(name) { send("_#{name}") } if options[:instance_reader] != false
- define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
+ # If an instance_reader is needed, generate public instance methods name and name?.
+ if options[:instance_reader] != false
+ define_method(name) { send("_#{name}") }
+ define_method("#{name}?") { !!send("#{name}") }
+ end
end
private
diff --git a/activesupport/lib/active_support/core_ext/hash/except.rb b/activesupport/lib/active_support/core_ext/hash/except.rb
index d90e996ad4..682d089881 100644
--- a/activesupport/lib/active_support/core_ext/hash/except.rb
+++ b/activesupport/lib/active_support/core_ext/hash/except.rb
@@ -1,5 +1,5 @@
class Hash
- # Return a hash that includes everything but the given keys. This is useful for
+ # Returns a hash that includes everything but the given keys. This is useful for
# limiting a set of parameters to everything but a few known toggles:
#
# @person.update(params[:person].except(:admin))
diff --git a/activesupport/lib/active_support/core_ext/hash/keys.rb b/activesupport/lib/active_support/core_ext/hash/keys.rb
index 93e716585b..3d41aa8572 100644
--- a/activesupport/lib/active_support/core_ext/hash/keys.rb
+++ b/activesupport/lib/active_support/core_ext/hash/keys.rb
@@ -1,5 +1,5 @@
class Hash
- # Return a new hash with all keys converted using the block operation.
+ # Returns a new hash with all keys converted using the block operation.
#
# hash = { name: 'Rob', age: '28' }
#
@@ -22,7 +22,7 @@ class Hash
self
end
- # Return a new hash with all keys converted to strings.
+ # Returns a new hash with all keys converted to strings.
#
# hash = { name: 'Rob', age: '28' }
#
@@ -38,7 +38,7 @@ class Hash
transform_keys!{ |key| key.to_s }
end
- # Return a new hash with all keys converted to symbols, as long as
+ # Returns a new hash with all keys converted to symbols, as long as
# they respond to +to_sym+.
#
# hash = { 'name' => 'Rob', 'age' => '28' }
@@ -73,7 +73,7 @@ class Hash
end
end
- # Return a new hash with all keys converted by the block operation.
+ # Returns a new hash with all keys converted by the block operation.
# This includes the keys from the root hash and from all
# nested hashes.
#
@@ -100,7 +100,7 @@ class Hash
self
end
- # Return a new hash with all keys converted to strings.
+ # Returns a new hash with all keys converted to strings.
# This includes the keys from the root hash and from all
# nested hashes.
#
@@ -119,7 +119,7 @@ class Hash
deep_transform_keys!{ |key| key.to_s }
end
- # Return a new hash with all keys converted to symbols, as long as
+ # Returns a new hash with all keys converted to symbols, as long as
# they respond to +to_sym+. This includes the keys from the root hash
# and from all nested hashes.
#
diff --git a/activesupport/lib/active_support/core_ext/module.rb b/activesupport/lib/active_support/core_ext/module.rb
index f2d4887df6..b4efff8b24 100644
--- a/activesupport/lib/active_support/core_ext/module.rb
+++ b/activesupport/lib/active_support/core_ext/module.rb
@@ -4,6 +4,7 @@ require 'active_support/core_ext/module/anonymous'
require 'active_support/core_ext/module/reachable'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/module/attr_internal'
+require 'active_support/core_ext/module/concerning'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/deprecation'
require 'active_support/core_ext/module/remove_method'
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
index f70a839074..d317df5079 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb
@@ -49,7 +49,7 @@ class Module
# include HairColors
# end
#
- # Person.hair_colors # => [:brown, :black, :blonde, :red] + #
+ # Person.hair_colors # => [:brown, :black, :blonde, :red]
def mattr_reader(*syms)
options = syms.extract_options!
syms.each do |sym|
@@ -181,7 +181,7 @@ class Module
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
#
# module HairColors
- # mattr_accessor :hair_colors, instance_acessor: false
+ # mattr_accessor :hair_colors, instance_accessor: false
# end
#
# class Person
diff --git a/activesupport/lib/active_support/core_ext/module/concerning.rb b/activesupport/lib/active_support/core_ext/module/concerning.rb
new file mode 100644
index 0000000000..b22dc5ff1e
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/module/concerning.rb
@@ -0,0 +1,135 @@
+require 'active_support/concern'
+
+class Module
+ # = Bite-sized separation of concerns
+ #
+ # We often find ourselves with a medium-sized chunk of behavior that we'd
+ # like to extract, but only mix in to a single class.
+ #
+ # Extracting a plain old Ruby object to encapsulate it and collaborate or
+ # delegate to the original object is often a good choice, but when there's
+ # no additional state to encapsulate or we're making DSL-style declarations
+ # about the parent class, introducing new collaborators can obfuscate rather
+ # than simplify.
+ #
+ # The typical route is to just dump everything in a monolithic class, perhaps
+ # with a comment, as a least-bad alternative. Using modules in separate files
+ # means tedious sifting to get a big-picture view.
+ #
+ # = Dissatisfying ways to separate small concerns
+ #
+ # == Using comments:
+ #
+ # class Todo
+ # # Other todo implementation
+ # # ...
+ #
+ # ## Event tracking
+ # has_many :events
+ #
+ # before_create :track_creation
+ # after_destroy :track_deletion
+ #
+ # private
+ # def track_creation
+ # # ...
+ # end
+ # end
+ #
+ # == With an inline module:
+ #
+ # Noisy syntax.
+ #
+ # class Todo
+ # # Other todo implementation
+ # # ...
+ #
+ # module EventTracking
+ # extend ActiveSupport::Concern
+ #
+ # included do
+ # has_many :events
+ # before_create :track_creation
+ # after_destroy :track_deletion
+ # end
+ #
+ # private
+ # def track_creation
+ # # ...
+ # end
+ # end
+ # include EventTracking
+ # end
+ #
+ # == Mix-in noise exiled to its own file:
+ #
+ # Once our chunk of behavior starts pushing the scroll-to-understand it
+ # boundary, we give in and move it to a separate file. At this size, the
+ # overhead feels in good proportion to the size of our extraction, despite
+ # diluting our at-a-glance sense of how things really work.
+ #
+ # class Todo
+ # # Other todo implementation
+ # # ...
+ #
+ # include TodoEventTracking
+ # end
+ #
+ # = Introducing Module#concerning
+ #
+ # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to
+ # separate bite-sized concerns.
+ #
+ # class Todo
+ # # Other todo implementation
+ # # ...
+ #
+ # concerning :EventTracking do
+ # included do
+ # has_many :events
+ # before_create :track_creation
+ # after_destroy :track_deletion
+ # end
+ #
+ # private
+ # def track_creation
+ # # ...
+ # end
+ # end
+ # end
+ #
+ # Todo.ancestors
+ # # => Todo, Todo::EventTracking, Object
+ #
+ # This small step has some wonderful ripple effects. We can
+ # * grok the behavior of our class in one glance,
+ # * clean up monolithic junk-drawer classes by separating their concerns, and
+ # * stop leaning on protected/private for crude "this is internal stuff" modularity.
+ module Concerning
+ # Define a new concern and mix it in.
+ def concerning(topic, &block)
+ include concern(topic, &block)
+ end
+
+ # A low-cruft shortcut to define a concern.
+ #
+ # concern :EventTracking do
+ # ...
+ # end
+ #
+ # is equivalent to
+ #
+ # module EventTracking
+ # extend ActiveSupport::Concern
+ #
+ # ...
+ # end
+ def concern(topic, &module_definition)
+ const_set topic, Module.new {
+ extend ::ActiveSupport::Concern
+ module_eval(&module_definition)
+ }
+ end
+ end
+ include Concerning
+end
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 1b2098fc84..1b20507c0b 100644
--- a/activesupport/lib/active_support/core_ext/string/output_safety.rb
+++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb
@@ -183,15 +183,14 @@ module ActiveSupport #:nodoc:
end
def %(args)
- args = Array(args).map do |arg|
- if !html_safe? || arg.html_safe?
- arg
- else
- ERB::Util.h(arg)
- end
+ case args
+ when Hash
+ escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
+ else
+ escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
end
- self.class.new(super(args))
+ self.class.new(super(escaped_args))
end
def html_safe?
@@ -224,6 +223,12 @@ module ActiveSupport #:nodoc:
EOT
end
end
+
+ private
+
+ def html_escape_interpolated_argument(arg)
+ (!html_safe? || arg.html_safe?) ? arg : ERB::Util.h(arg)
+ end
end
end
diff --git a/activesupport/lib/active_support/core_ext/thread.rb b/activesupport/lib/active_support/core_ext/thread.rb
index d5a420301a..ac1ffa4128 100644
--- a/activesupport/lib/active_support/core_ext/thread.rb
+++ b/activesupport/lib/active_support/core_ext/thread.rb
@@ -33,7 +33,7 @@ class Thread
_locals[key.to_sym] = value
end
- # Returns an an array of the names of the thread-local variables (as Symbols).
+ # Returns an array of the names of the thread-local variables (as Symbols).
#
# thr = Thread.new do
# Thread.current.thread_variable_set(:cat, 'meow')
diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb
index dcdea70443..23cd6716e3 100644
--- a/activesupport/lib/active_support/i18n_railtie.rb
+++ b/activesupport/lib/active_support/i18n_railtie.rb
@@ -8,6 +8,8 @@ module I18n
config.i18n.railties_load_path = []
config.i18n.load_path = []
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
+ # Enforce I18n to check the available locales when setting a locale.
+ config.i18n.enforce_available_locales = true
# Set the i18n configuration after initialization since a lot of
# configuration is still usually done in application initializers.
@@ -31,10 +33,11 @@ module I18n
fallbacks = app.config.i18n.delete(:fallbacks)
- if app.config.i18n.has_key?(:enforce_available_locales)
- # this option needs to be set before `default_locale=` to work properly.
- I18n.enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
- end
+ # Avoid issues with setting the default_locale by disabling available locales
+ # check while configuring.
+ enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
+ enforce_available_locales = I18n.enforce_available_locales unless I18n.enforce_available_locales.nil?
+ I18n.enforce_available_locales = false
app.config.i18n.each do |setting, value|
case setting
@@ -49,6 +52,9 @@ module I18n
init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks)
+ # Restore available locales check so it will take place from now on.
+ I18n.enforce_available_locales = enforce_available_locales
+
reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
app.reloaders << reloader
ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb
index 060dcb6995..2859075e10 100644
--- a/activesupport/lib/active_support/json/encoding.rb
+++ b/activesupport/lib/active_support/json/encoding.rb
@@ -63,33 +63,28 @@ module ActiveSupport
private_constant :ESCAPED_CHARS, :ESCAPE_REGEX_WITH_HTML_ENTITIES,
:ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString
- # Recursively turn the given object into a "jsonified" Ruby data structure
- # that the JSON gem understands - i.e. we want only Hash, Array, String,
- # Numeric, true, false and nil in the final tree. Calls #as_json on it if
- # it's not from one of these base types.
- #
- # This allows developers to implement #as_json withouth having to worry
- # about what base types of objects they are allowed to return and having
- # to remember calling #as_json recursively.
- #
- # By default, the options hash is not passed to the children data structures
- # to avoid undesiarable result. Develoers must opt-in by implementing
- # custom #as_json methods (e.g. Hash#as_json and Array#as_json).
+ # Convert an object into a "JSON-ready" representation composed of
+ # primitives like Hash, Array, String, Numeric, and true/false/nil.
+ # Recursively calls #as_json to the object to recursively build a
+ # fully JSON-ready object.
+ #
+ # This allows developers to implement #as_json without having to
+ # worry about what base types of objects they are allowed to return
+ # or having to remember to call #as_json recursively.
+ #
+ # Note: the +options+ hash passed to +object.to_json+ is only passed
+ # to +object.as_json+, not any of this method's recursive +#as_json+
+ # calls.
def jsonify(value)
- if value.is_a?(Hash)
- Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
- elsif value.is_a?(Array)
- value.map { |v| jsonify(v) }
- elsif value.is_a?(String)
+ case value
+ when String
EscapedString.new(value)
- elsif value.is_a?(Numeric)
+ when Numeric, NilClass, TrueClass, FalseClass
value
- elsif value == true
- true
- elsif value == false
- false
- elsif value == nil
- nil
+ when Hash
+ Hash[value.map { |k, v| [jsonify(k), jsonify(v)] }]
+ when Array
+ value.map { |v| jsonify(v) }
else
jsonify value.as_json
end
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
index a35d5980fe..8e6e1dcfeb 100644
--- a/activesupport/lib/active_support/message_verifier.rb
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -39,8 +39,9 @@ module ActiveSupport
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
begin
@serializer.load(::Base64.strict_decode64(data))
- rescue ArgumentError
- raise InvalidSignature
+ rescue ArgumentError => argument_error
+ raise InvalidSignature if argument_error.message =~ %r{invalid base64}
+ raise
end
else
raise InvalidSignature
diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb
index c6658dba96..b169e3af01 100644
--- a/activesupport/lib/active_support/number_helper.rb
+++ b/activesupport/lib/active_support/number_helper.rb
@@ -1,4 +1,3 @@
-
module ActiveSupport
module NumberHelper
extend ActiveSupport::Autoload
@@ -343,6 +342,5 @@ module ActiveSupport
def number_to_human(number, options = {})
NumberToHumanConverter.convert(number, options)
end
-
end
end
diff --git a/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb b/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
index d1335f6910..78d2c9ae6e 100644
--- a/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_human_size_converter.rb
@@ -1,6 +1,6 @@
module ActiveSupport
module NumberHelper
- class NumberToHumanSizeConverter < NumberConverter
+ class NumberToHumanSizeConverter < NumberConverter #:nodoc:
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
self.namespace = :human
diff --git a/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb b/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
index 4c33c30772..af2ee56d91 100644
--- a/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_phone_converter.rb
@@ -1,6 +1,6 @@
module ActiveSupport
module NumberHelper
- class NumberToPhoneConverter < NumberConverter
+ class NumberToPhoneConverter < NumberConverter #:nodoc:
def convert
str = country_code(opts[:country_code])
str << convert_to_phone_number(number.to_s.strip)
diff --git a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
index 273667fdae..c42354fc83 100644
--- a/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
+++ b/activesupport/lib/active_support/number_helper/number_to_rounded_converter.rb
@@ -5,28 +5,50 @@ module ActiveSupport
self.validate_float = true
def convert
- @number = Float(number)
-
precision = options.delete :precision
significant = options.delete :significant
+ case number
+ when Float, String
+ @number = BigDecimal(number.to_s)
+ when Rational
+ if significant
+ @number = BigDecimal(number, digit_count(number.to_i) + precision)
+ else
+ @number = BigDecimal(number, precision)
+ end
+ else
+ @number = number.to_d
+ end
+
if significant && precision > 0
digits, rounded_number = digits_and_rounded_number(precision)
precision -= digits
precision = 0 if precision < 0 # don't let it be negative
else
- rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
+ rounded_number = number.round(precision)
+ rounded_number = rounded_number.to_i if precision == 0
rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
end
- delimited_number = NumberToDelimitedConverter.convert("%01.#{precision}f" % rounded_number, options)
+ formatted_string =
+ case rounded_number
+ when BigDecimal
+ s = rounded_number.to_s('F') + '0'*precision
+ a, b = s.split('.', 2)
+ a + '.' + b[0, precision]
+ else
+ "%01.#{precision}f" % rounded_number
+ end
+
+ delimited_number = NumberToDelimitedConverter.convert(formatted_string, options)
format_number(delimited_number)
end
private
def digits_and_rounded_number(precision)
- if number.zero?
+ if zero?
[1, 0]
else
digits = digit_count(number)
@@ -38,11 +60,11 @@ module ActiveSupport
end
def calculate_rounded_number(multiplier)
- (BigDecimal.new(number.to_s) / BigDecimal.new(multiplier.to_f.to_s)).round.to_f * multiplier
+ (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
end
def digit_count(number)
- (Math.log10(number.abs) + 1).floor
+ (Math.log10(absolute_number(number)) + 1).floor
end
def strip_insignificant_zeros
@@ -57,6 +79,14 @@ module ActiveSupport
number
end
end
+
+ def absolute_number(number)
+ number.respond_to?(:abs) ? number.abs : number.to_d.abs
+ end
+
+ def zero?
+ number.respond_to?(:zero?) ? number.zero? : number.to_d.zero?
+ end
end
end
end
diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb
index a5e7389d16..ca2e4d5625 100644
--- a/activesupport/lib/active_support/per_thread_registry.rb
+++ b/activesupport/lib/active_support/per_thread_registry.rb
@@ -32,12 +32,15 @@ module ActiveSupport
#
# If the class has an initializer, it must accept no arguments.
module PerThreadRegistry
+ def self.extended(object)
+ object.instance_variable_set '@per_thread_registry_key', object.name.freeze
+ end
+
def instance
- Thread.current[name] ||= new
+ Thread.current[@per_thread_registry_key] ||= new
end
protected
-
def method_missing(name, *args, &block) # :nodoc:
# Caches the method definition as a singleton method of the receiver.
define_singleton_method(name) do |*a, &b|
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index a22e61d286..3862ab5c42 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -359,14 +359,14 @@ module ActiveSupport
class << self
alias_method :create, :new
- # Return a TimeZone instance with the given name, or +nil+ if no
+ # Returns a TimeZone instance with the given name, or +nil+ if no
# such TimeZone instance exists. (This exists to support the use of
# this class with the +composed_of+ macro.)
def new(name)
self[name]
end
- # Return an array of all TimeZone objects. There are multiple
+ # Returns an array of all TimeZone objects. There are multiple
# TimeZone objects per time zone, in many cases, to make it easier
# for users to find their own time zone.
def all
diff --git a/activesupport/lib/active_support/version.rb b/activesupport/lib/active_support/version.rb
index 8762330a6e..b3f0e7198d 100644
--- a/activesupport/lib/active_support/version.rb
+++ b/activesupport/lib/active_support/version.rb
@@ -1,7 +1,7 @@
module ActiveSupport
# Returns the version of the currently loaded ActiveSupport as a Gem::Version
def self.version
- Gem::Version.new "4.1.0.beta"
+ Gem::Version.new "4.1.0.beta1"
end
module VERSION #:nodoc:
diff --git a/activesupport/test/abstract_unit.rb b/activesupport/test/abstract_unit.rb
index 65de48a7f6..1dfa3833f0 100644
--- a/activesupport/test/abstract_unit.rb
+++ b/activesupport/test/abstract_unit.rb
@@ -15,7 +15,6 @@ silence_warnings do
end
require 'active_support/testing/autorun'
-require 'empty_bool'
ENV['NO_RELOAD'] = '1'
require 'active_support'
@@ -25,6 +24,9 @@ Thread.abort_on_exception = true
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
+# Disable available locale checks to avoid warnings running the test suite.
+I18n.enforce_available_locales = false
+
# Skips the current run on Rubinius using Minitest::Assertions#skip
def rubinius_skip(message = '')
skip message if RUBY_ENGINE == 'rbx'
diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb
index f8e2ce22fa..32c2dfdfc0 100644
--- a/activesupport/test/callbacks_test.rb
+++ b/activesupport/test/callbacks_test.rb
@@ -1,27 +1,6 @@
require 'abstract_unit'
module CallbacksTest
- class Phone
- include ActiveSupport::Callbacks
- define_callbacks :save
-
- set_callback :save, :before, :before_save1
- set_callback :save, :after, :after_save1
-
- def before_save1; self.history << :before; end
- def after_save1; self.history << :after; end
-
- def save
- run_callbacks :save do
- raise 'boom'
- end
- end
-
- def history
- @history ||= []
- end
- end
-
class Record
include ActiveSupport::Callbacks
diff --git a/activesupport/test/configurable_test.rb b/activesupport/test/configurable_test.rb
index d00273a028..ef847fc557 100644
--- a/activesupport/test/configurable_test.rb
+++ b/activesupport/test/configurable_test.rb
@@ -95,6 +95,20 @@ class ConfigurableActiveSupport < ActiveSupport::TestCase
config_accessor "invalid attribute name"
end
end
+
+ assert_raises NameError do
+ Class.new do
+ include ActiveSupport::Configurable
+ config_accessor "invalid\nattribute"
+ end
+ end
+
+ assert_raises NameError do
+ Class.new do
+ include ActiveSupport::Configurable
+ config_accessor "invalid\n"
+ end
+ end
end
def assert_method_defined(object, method)
diff --git a/activesupport/test/core_ext/blank_test.rb b/activesupport/test/core_ext/blank_test.rb
index a68c074777..3e3176f993 100644
--- a/activesupport/test/core_ext/blank_test.rb
+++ b/activesupport/test/core_ext/blank_test.rb
@@ -4,6 +4,14 @@ require 'abstract_unit'
require 'active_support/core_ext/object/blank'
class BlankTest < ActiveSupport::TestCase
+ class EmptyTrue
+ def empty?() true; end
+ end
+
+ class EmptyFalse
+ def empty?() false; end
+ end
+
BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", ' ', [], {} ]
NOT = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ]
diff --git a/activesupport/test/core_ext/class/delegating_attributes_test.rb b/activesupport/test/core_ext/class/delegating_attributes_test.rb
index 148f82946c..0e0742d147 100644
--- a/activesupport/test/core_ext/class/delegating_attributes_test.rb
+++ b/activesupport/test/core_ext/class/delegating_attributes_test.rb
@@ -39,10 +39,13 @@ class DelegatingAttributesTest < ActiveSupport::TestCase
end
def test_simple_accessor_declaration_with_instance_reader_false
+ _instance_methods = single_class.public_instance_methods
single_class.superclass_delegating_accessor :no_instance_reader, :instance_reader => false
assert_respond_to single_class, :no_instance_reader
assert_respond_to single_class, :no_instance_reader=
- assert !single_class.public_instance_methods.map(&:to_s).include?("no_instance_reader")
+ assert !_instance_methods.include?(:no_instance_reader)
+ assert !_instance_methods.include?(:no_instance_reader?)
+ assert !_instance_methods.include?(:_no_instance_reader)
end
def test_working_with_simple_attributes
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index 8eae8c832c..28ba33331e 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -53,12 +53,10 @@ class DurationTest < ActiveSupport::TestCase
end
def test_argument_error
- 1.second.ago('')
- flunk("no exception was raised")
- rescue ArgumentError => e
+ e = assert_raise ArgumentError do
+ 1.second.ago('')
+ end
assert_equal 'expected a time or date, got ""', e.message, "ensure ArgumentError is not being raised by dependencies.rb"
- rescue Exception => e
- flunk("ArgumentError should be raised, but we got #{e.class} instead")
end
def test_fractional_weeks
diff --git a/activesupport/test/core_ext/module/concerning_test.rb b/activesupport/test/core_ext/module/concerning_test.rb
new file mode 100644
index 0000000000..c6863b24a4
--- /dev/null
+++ b/activesupport/test/core_ext/module/concerning_test.rb
@@ -0,0 +1,35 @@
+require 'abstract_unit'
+require 'active_support/core_ext/module/concerning'
+
+class ConcerningTest < ActiveSupport::TestCase
+ def test_concern_shortcut_creates_a_module_but_doesnt_include_it
+ mod = Module.new { concern(:Foo) { } }
+ assert_kind_of Module, mod::Foo
+ assert mod::Foo.respond_to?(:included)
+ assert !mod.ancestors.include?(mod::Foo), mod.ancestors.inspect
+ end
+
+ def test_concern_creates_a_module_extended_with_active_support_concern
+ klass = Class.new do
+ concern :Foo do
+ included { @foo = 1 }
+ def should_be_public; end
+ end
+ end
+
+ # Declares a concern but doesn't include it
+ assert_kind_of Module, klass::Foo
+ assert !klass.ancestors.include?(klass::Foo), klass.ancestors.inspect
+
+ # Public method visibility by default
+ assert klass::Foo.public_instance_methods.map(&:to_s).include?('should_be_public')
+
+ # Calls included hook
+ assert_equal 1, Class.new { include klass::Foo }.instance_variable_get('@foo')
+ end
+
+ def test_concerning_declares_a_concern_and_includes_it_immediately
+ klass = Class.new { concerning(:Foo) { } }
+ assert klass.ancestors.include?(klass::Foo), klass.ancestors.inspect
+ end
+end
diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb
index 283b13ff8b..5b99fae411 100644
--- a/activesupport/test/core_ext/module_test.rb
+++ b/activesupport/test/core_ext/module_test.rb
@@ -12,12 +12,6 @@ class Ab
Constant3 = "Goodbye World"
end
-module Xy
- class Bc
- include One
- end
-end
-
module Yz
module Zy
class Cd
diff --git a/activesupport/test/core_ext/name_error_test.rb b/activesupport/test/core_ext/name_error_test.rb
index 03ce09f22a..7525f80cf0 100644
--- a/activesupport/test/core_ext/name_error_test.rb
+++ b/activesupport/test/core_ext/name_error_test.rb
@@ -3,18 +3,18 @@ require 'active_support/core_ext/name_error'
class NameErrorTest < ActiveSupport::TestCase
def test_name_error_should_set_missing_name
- SomeNameThatNobodyWillUse____Really ? 1 : 0
- flunk "?!?!"
- rescue NameError => exc
+ exc = assert_raise NameError do
+ SomeNameThatNobodyWillUse____Really ? 1 : 0
+ end
assert_equal "NameErrorTest::SomeNameThatNobodyWillUse____Really", exc.missing_name
assert exc.missing_name?(:SomeNameThatNobodyWillUse____Really)
assert exc.missing_name?("NameErrorTest::SomeNameThatNobodyWillUse____Really")
end
def test_missing_method_should_ignore_missing_name
- some_method_that_does_not_exist
- flunk "?!?!"
- rescue NameError => exc
+ exc = assert_raise NameError do
+ some_method_that_does_not_exist
+ end
assert !exc.missing_name?(:Foo)
assert_nil exc.missing_name
end
diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb
index 8d748791e3..0f454fdd95 100644
--- a/activesupport/test/core_ext/object_and_class_ext_test.rb
+++ b/activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -3,31 +3,6 @@ require 'active_support/time'
require 'active_support/core_ext/object'
require 'active_support/core_ext/class/subclasses'
-class ClassA; end
-class ClassB < ClassA; end
-class ClassC < ClassB; end
-class ClassD < ClassA; end
-
-class ClassI; end
-class ClassJ < ClassI; end
-
-class ClassK
-end
-module Nested
- class << self
- def on_const_missing(&callback)
- @on_const_missing = callback
- end
- private
- def const_missing(mod_id)
- @on_const_missing[mod_id] if @on_const_missing
- super
- end
- end
- class ClassL < ClassK
- end
-end
-
class ObjectTests < ActiveSupport::TestCase
class DuckTime
def acts_like_time?
diff --git a/activesupport/test/dependencies_test.rb b/activesupport/test/dependencies_test.rb
index e56bab6d4c..00bec5bd9d 100644
--- a/activesupport/test/dependencies_test.rb
+++ b/activesupport/test/dependencies_test.rb
@@ -73,12 +73,11 @@ class DependenciesTest < ActiveSupport::TestCase
$raises_exception_load_count = 0
5.times do |count|
- begin
+ e = assert_raise Exception, 'should have loaded dependencies/raises_exception which raises an exception' do
require_dependency filename
- flunk 'should have loaded dependencies/raises_exception which raises an exception'
- rescue Exception => e
- assert_equal 'Loading me failed, so do not add to loaded or history.', e.message
end
+
+ assert_equal 'Loading me failed, so do not add to loaded or history.', e.message
assert_equal count + 1, $raises_exception_load_count
assert !ActiveSupport::Dependencies.loaded.include?(filename)
@@ -366,26 +365,19 @@ class DependenciesTest < ActiveSupport::TestCase
def test_non_existing_const_raises_name_error_with_fully_qualified_name
with_autoloading_fixtures do
- begin
- A::DoesNotExist.nil?
- flunk "No raise!!"
- rescue NameError => e
- assert_equal "uninitialized constant A::DoesNotExist", e.message
- end
- begin
- A::B::DoesNotExist.nil?
- flunk "No raise!!"
- rescue NameError => e
- assert_equal "uninitialized constant A::B::DoesNotExist", e.message
- end
+ e = assert_raise(NameError) { A::DoesNotExist.nil? }
+ assert_equal "uninitialized constant A::DoesNotExist", e.message
+
+ e = assert_raise(NameError) { A::B::DoesNotExist.nil? }
+ assert_equal "uninitialized constant A::B::DoesNotExist", e.message
end
end
def test_smart_name_error_strings
- Object.module_eval "ImaginaryObject"
- flunk "No raise!!"
- rescue NameError => e
- assert e.message.include?("uninitialized constant ImaginaryObject")
+ e = assert_raise NameError do
+ Object.module_eval "ImaginaryObject"
+ end
+ assert_includes "uninitialized constant ImaginaryObject", e.message
end
def test_loadable_constants_for_path_should_handle_empty_autoloads
@@ -543,8 +535,8 @@ class DependenciesTest < ActiveSupport::TestCase
require_dependency 'e'
mod = Module.new
- msg = 'E cannot be autoloaded from an anonymous class or module'
- assert_raise(NameError, msg) { mod::E }
+ e = assert_raise(NameError) { mod::E }
+ assert_equal 'E cannot be autoloaded from an anonymous class or module', e.message
end
end
@@ -553,12 +545,10 @@ class DependenciesTest < ActiveSupport::TestCase
c = ServiceOne
ActiveSupport::Dependencies.clear
assert ! defined?(ServiceOne)
- begin
+ e = assert_raise ArgumentError do
ActiveSupport::Dependencies.load_missing_constant(c, :FakeMissing)
- flunk "Expected exception"
- rescue ArgumentError => e
- assert_match %r{ServiceOne has been removed from the module tree}i, e.message
end
+ assert_match %r{ServiceOne has been removed from the module tree}i, e.message
end
end
@@ -897,12 +887,10 @@ class DependenciesTest < ActiveSupport::TestCase
with_autoloading_fixtures do
Object.send(:remove_const, :RaisesNameError) if defined?(::RaisesNameError)
2.times do
- begin
+ e = assert_raise NameError do
::RaisesNameError::FooBarBaz.object_id
- flunk 'should have raised NameError when autoloaded file referenced FooBarBaz'
- rescue NameError => e
- assert_equal 'uninitialized constant RaisesNameError::FooBarBaz', e.message
end
+ assert_equal 'uninitialized constant RaisesNameError::FooBarBaz', e.message
assert !defined?(::RaisesNameError), "::RaisesNameError is defined but it should have failed!"
end
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index 9674851b9d..ee1c69502e 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -104,14 +104,11 @@ class DeprecationTest < ActiveSupport::TestCase
message = 'Revise this deprecated stuff now!'
callstack = %w(foo bar baz)
- begin
+ e = assert_raise ActiveSupport::DeprecationException do
ActiveSupport::Deprecation.behavior.first.call(message, callstack)
- rescue ActiveSupport::DeprecationException => e
- assert_equal message, e.message
- assert_equal callstack, e.backtrace
- else
- flunk 'the :raise deprecation behaviour should raise the expected exception'
end
+ assert_equal message, e.message
+ assert_equal callstack, e.backtrace
end
def test_default_stderr_behavior
@@ -174,7 +171,7 @@ class DeprecationTest < ActiveSupport::TestCase
ActiveSupport::Deprecation.warn 'abc'
ActiveSupport::Deprecation.warn 'def'
end
- rescue MiniTest::Assertion
+ rescue Minitest::Assertion
flunk 'assert_deprecated should match any warning in block, not just the last one'
end
diff --git a/activesupport/test/empty_bool.rb b/activesupport/test/empty_bool.rb
deleted file mode 100644
index 005b3523ef..0000000000
--- a/activesupport/test/empty_bool.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class EmptyTrue
- def empty?() true; end
-end
-
-class EmptyFalse
- def empty?() false; end
-end
diff --git a/activesupport/test/fixtures/custom.rb b/activesupport/test/fixtures/custom.rb
deleted file mode 100644
index 0eefce0c25..0000000000
--- a/activesupport/test/fixtures/custom.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-class Custom
-end \ No newline at end of file
diff --git a/activesupport/test/message_verifier_test.rb b/activesupport/test/message_verifier_test.rb
index f208814468..a5748d28ba 100644
--- a/activesupport/test/message_verifier_test.rb
+++ b/activesupport/test/message_verifier_test.rb
@@ -55,6 +55,20 @@ class MessageVerifierTest < ActiveSupport::TestCase
ActiveSupport.use_standard_json_time_format = prev
end
+ def test_raise_error_when_argument_class_is_not_loaded
+ # To generate the valid message below:
+ #
+ # AutoloadClass = Struct.new(:foo)
+ # valid_message = @verifier.generate(foo: AutoloadClass.new('foo'))
+ #
+ valid_message = "BAh7BjoIZm9vbzonTWVzc2FnZVZlcmlmaWVyVGVzdDo6QXV0b2xvYWRDbGFzcwY6CUBmb29JIghmb28GOgZFVA==--f3ef39a5241c365083770566dc7a9eb5d6ace914"
+ exception = assert_raise(ArgumentError, NameError) do
+ @verifier.verify(valid_message)
+ end
+ assert_includes ["uninitialized constant MessageVerifierTest::AutoloadClass",
+ "undefined class/module MessageVerifierTest::AutoloadClass"], exception.message
+ end
+
def assert_not_verified(message)
assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
@verifier.verify(message)
diff --git a/activesupport/test/multibyte_chars_test.rb b/activesupport/test/multibyte_chars_test.rb
index 2bf73291a2..659fceb852 100644
--- a/activesupport/test/multibyte_chars_test.rb
+++ b/activesupport/test/multibyte_chars_test.rb
@@ -221,9 +221,9 @@ class MultibyteCharsUTF8BehaviourTest < ActiveSupport::TestCase
end
def test_include_raises_when_nil_is_passed
- @chars.include?(nil)
- flunk "Expected chars.include?(nil) to raise TypeError or NoMethodError"
- rescue Exception
+ assert_raises TypeError, NoMethodError, "Expected chars.include?(nil) to raise TypeError or NoMethodError" do
+ @chars.include?(nil)
+ end
end
def test_index_should_return_character_offset
diff --git a/activesupport/test/number_helper_test.rb b/activesupport/test/number_helper_test.rb
index 111db59b2b..6d8d835de7 100644
--- a/activesupport/test/number_helper_test.rb
+++ b/activesupport/test/number_helper_test.rb
@@ -123,6 +123,12 @@ module ActiveSupport
assert_equal("10.00", number_helper.number_to_rounded(9.995, :precision => 2))
assert_equal("11.00", number_helper.number_to_rounded(10.995, :precision => 2))
assert_equal("0.00", number_helper.number_to_rounded(-0.001, :precision => 2))
+
+ assert_equal("111.23460000000000000000", number_helper.number_to_rounded(111.2346, :precision => 20))
+ assert_equal("111.23460000000000000000", number_helper.number_to_rounded(Rational(1112346, 10000), :precision => 20))
+ assert_equal("111.23460000000000000000", number_helper.number_to_rounded('111.2346', :precision => 20))
+ assert_equal("111.23460000000000000000", number_helper.number_to_rounded(BigDecimal(111.2346, Float::DIG), :precision => 20))
+ assert_equal("111.2346" + "0"*96, number_helper.number_to_rounded('111.2346', :precision => 100))
end
end
@@ -155,6 +161,14 @@ module ActiveSupport
assert_equal "10.0", number_helper.number_to_rounded(9.995, :precision => 3, :significant => true)
assert_equal "9.99", number_helper.number_to_rounded(9.994, :precision => 3, :significant => true)
assert_equal "11.0", number_helper.number_to_rounded(10.995, :precision => 3, :significant => true)
+
+ assert_equal "9775.0000000000000000", number_helper.number_to_rounded(9775, :precision => 20, :significant => true )
+ assert_equal "9775.0000000000000000", number_helper.number_to_rounded(9775.0, :precision => 20, :significant => true )
+ assert_equal "9775.0000000000000000", number_helper.number_to_rounded(Rational(9775, 1), :precision => 20, :significant => true )
+ assert_equal "97.750000000000000000", number_helper.number_to_rounded(Rational(9775, 100), :precision => 20, :significant => true )
+ assert_equal "9775.0000000000000000", number_helper.number_to_rounded(BigDecimal(9775), :precision => 20, :significant => true )
+ assert_equal "9775.0000000000000000", number_helper.number_to_rounded("9775", :precision => 20, :significant => true )
+ assert_equal "9775." + "0"*96, number_helper.number_to_rounded("9775", :precision => 100, :significant => true )
end
end
diff --git a/activesupport/test/safe_buffer_test.rb b/activesupport/test/safe_buffer_test.rb
index 047b89be2a..efa9d5e61f 100644
--- a/activesupport/test/safe_buffer_test.rb
+++ b/activesupport/test/safe_buffer_test.rb
@@ -140,4 +140,29 @@ class SafeBufferTest < ActiveSupport::TestCase
# should still be unsafe
assert !y.html_safe?, "should not be safe"
end
+
+ test 'Should work with interpolation (array argument)' do
+ x = 'foo %s bar'.html_safe % ['qux']
+ assert_equal 'foo qux bar', x
+ end
+
+ test 'Should work with interpolation (hash argument)' do
+ x = 'foo %{x} bar'.html_safe % { x: 'qux' }
+ assert_equal 'foo qux bar', x
+ end
+
+ test 'Should escape unsafe interpolated args' do
+ x = 'foo %{x} bar'.html_safe % { x: '<br/>' }
+ assert_equal 'foo &lt;br/&gt; bar', x
+ end
+
+ test 'Should not escape safe interpolated args' do
+ x = 'foo %{x} bar'.html_safe % { x: '<br/>'.html_safe }
+ assert_equal 'foo <br/> bar', x
+ end
+
+ test 'Should interpolate to a safe string' do
+ x = 'foo %{x} bar'.html_safe % { x: 'qux' }
+ assert x.html_safe?, 'should be safe'
+ end
end
diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb
index 5ed2da7e8b..8a71ef4324 100644
--- a/activesupport/test/test_test.rb
+++ b/activesupport/test/test_test.rb
@@ -21,10 +21,10 @@ class AssertDifferenceTest < ActiveSupport::TestCase
assert_equal true, assert_not(nil)
assert_equal true, assert_not(false)
- e = assert_raises(MiniTest::Assertion) { assert_not true }
+ e = assert_raises(Minitest::Assertion) { assert_not true }
assert_equal 'Expected true to be nil or false', e.message
- e = assert_raises(MiniTest::Assertion) { assert_not true, 'custom' }
+ e = assert_raises(Minitest::Assertion) { assert_not true, 'custom' }
assert_equal 'custom', e.message
end
@@ -73,7 +73,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase
end
def test_array_of_expressions_identify_failure
- assert_raises(MiniTest::Assertion) do
+ assert_raises(Minitest::Assertion) do
assert_difference ['@object.num', '1 + 1'] do
@object.increment
end
@@ -81,7 +81,7 @@ class AssertDifferenceTest < ActiveSupport::TestCase
end
def test_array_of_expressions_identify_failure_when_message_provided
- assert_raises(MiniTest::Assertion) do
+ assert_raises(Minitest::Assertion) do
assert_difference ['@object.num', '1 + 1'], 1, 'something went wrong' do
@object.increment
end
diff --git a/activesupport/test/testing/constant_lookup_test.rb b/activesupport/test/testing/constant_lookup_test.rb
index aca2951450..71a9561189 100644
--- a/activesupport/test/testing/constant_lookup_test.rb
+++ b/activesupport/test/testing/constant_lookup_test.rb
@@ -6,7 +6,6 @@ class Bar < Foo
def index; end
def self.index; end
end
-class Baz < Bar; end
module FooBar; end
class ConstantLookupTest < ActiveSupport::TestCase