diff options
Diffstat (limited to 'activesupport/lib')
21 files changed, 178 insertions, 79 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 0f1de8b076..f32bb8a0cc 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -291,13 +291,11 @@ module ActiveSupport if !halted && user_conditions.all? { |c| c.call(target, value) } user_callback.call(target, value) { - env = run.call env - env.value + run.call.value } - env else - run.call env + run.call end end end @@ -309,11 +307,10 @@ module ActiveSupport value = env.value if env.halted - run.call env + run.call else user_callback.call(target, value) { - env = run.call env - env.value + run.call.value } env end @@ -328,12 +325,11 @@ module ActiveSupport if user_conditions.all? { |c| c.call(target, value) } user_callback.call(target, value) { - env = run.call env - env.value + run.call.value } env else - run.call env + run.call end end end @@ -342,8 +338,7 @@ module ActiveSupport def self.simple(callback_sequence, user_callback) callback_sequence.around do |env, &run| user_callback.call(env.target, env.value) { - env = run.call env - env.value + run.call.value } env end @@ -373,14 +368,14 @@ module ActiveSupport def filter; @key; end def raw_filter; @filter; end - def merge(chain, new_options) + def merge_conditional_options(chain, if_option:, unless_option:) options = { :if => @if.dup, :unless => @unless.dup } - options[:if].concat Array(new_options.fetch(:unless, [])) - options[:unless].concat Array(new_options.fetch(:if, [])) + options[:if].concat Array(unless_option) + options[:unless].concat Array(if_option) self.class.build chain, @filter, @kind, options end @@ -701,7 +696,7 @@ module ActiveSupport filter = chain.find {|c| c.matches?(type, filter) } if filter && options.any? - new_filter = filter.merge(chain, options) + new_filter = filter.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless]) chain.insert(chain.index(filter), new_filter) end @@ -746,8 +741,8 @@ module ActiveSupport # # * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after # callbacks should be terminated by the <tt>:terminator</tt> option. By - # default after callbacks executed no matter if callback chain was - # terminated or not. Option makes sense only when <tt>:terminator</tt> + # default after callbacks are executed no matter if callback chain was + # terminated or not. This option makes sense only when <tt>:terminator</tt> # option is specified. # # * <tt>:scope</tt> - Indicates which methods should be executed when an diff --git a/activesupport/lib/active_support/concern.rb b/activesupport/lib/active_support/concern.rb index 342d3a9d52..4082d2d464 100644 --- a/activesupport/lib/active_support/concern.rb +++ b/activesupport/lib/active_support/concern.rb @@ -114,7 +114,7 @@ module ActiveSupport return false else return false if base < self - @_dependencies.each { |dep| base.send(:include, dep) } + @_dependencies.each { |dep| base.include(dep) } super base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) diff --git a/activesupport/lib/active_support/configurable.rb b/activesupport/lib/active_support/configurable.rb index 3dd44e32d8..8256c325af 100644 --- a/activesupport/lib/active_support/configurable.rb +++ b/activesupport/lib/active_support/configurable.rb @@ -122,6 +122,7 @@ module ActiveSupport send("#{name}=", yield) if block_given? end end + private :config_accessor end # Reads and writes attributes from a configuration <tt>OrderedHash</tt>. diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb index 38374af388..fad6fa8d9d 100644 --- a/activesupport/lib/active_support/core_ext/file/atomic.rb +++ b/activesupport/lib/active_support/core_ext/file/atomic.rb @@ -20,7 +20,7 @@ class File temp_file = Tempfile.new(basename(file_name), temp_dir) temp_file.binmode - yield temp_file + return_val = yield temp_file temp_file.close if File.exist?(file_name) @@ -40,6 +40,9 @@ class File chown(old_stat.uid, old_stat.gid, file_name) # This operation will affect filesystem ACL's chmod(old_stat.mode, file_name) + + # Make sure we return the result of the yielded block + return_val rescue Errno::EPERM, Errno::EACCES # Changing file ownership failed, moving on. end diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 24df83800b..a5f4d03256 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -185,19 +185,31 @@ class Module # On the other hand it could be that the target has side-effects, # whereas conceptually, from the user point of view, the delegator should # be doing one call. - - exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") - - method_def = [ - "def #{method_prefix}#{method}(#{definition})", - " _ = #{to}", - " if !_.nil? || nil.respond_to?(:#{method})", - " _.#{method}(#{definition})", - " else", - " #{exception unless allow_nil}", - " end", + if allow_nil + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + "_ = #{to}", + "if !_.nil? || nil.respond_to?(:#{method})", + " _.#{method}(#{definition})", + "end", "end" - ].join ';' + ].join ';' + else + exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") + + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + " _ = #{to}", + " _.#{method}(#{definition})", + "rescue NoMethodError => e", + " if _.nil? && e.name == :#{method}", + " #{exception}", + " else", + " raise", + " end", + "end" + ].join ';' + end module_eval(method_def, file, line) end diff --git a/activesupport/lib/active_support/core_ext/name_error.rb b/activesupport/lib/active_support/core_ext/name_error.rb index b82148e4e5..6b447d772b 100644 --- a/activesupport/lib/active_support/core_ext/name_error.rb +++ b/activesupport/lib/active_support/core_ext/name_error.rb @@ -23,8 +23,7 @@ class NameError # # => true def missing_name?(name) if name.is_a? Symbol - last_name = (missing_name || '').split('::').last - last_name == name.to_s + self.name == name else missing_name == name.to_s end diff --git a/activesupport/lib/active_support/core_ext/string/multibyte.rb b/activesupport/lib/active_support/core_ext/string/multibyte.rb index a124202936..2eedd4fdb1 100644 --- a/activesupport/lib/active_support/core_ext/string/multibyte.rb +++ b/activesupport/lib/active_support/core_ext/string/multibyte.rb @@ -1,4 +1,3 @@ -# encoding: utf-8 require 'active_support/multibyte' class String 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 ba8d4acd6d..bae4e206e6 100644 --- a/activesupport/lib/active_support/core_ext/string/output_safety.rb +++ b/activesupport/lib/active_support/core_ext/string/output_safety.rb @@ -85,6 +85,11 @@ class ERB # automatically flag the result as HTML safe, since the raw value is unsafe to # use inside HTML attributes. # + # If your JSON is being used downstream for insertion into the DOM, be aware of + # whether or not it is being inserted via +html()+. Most JQuery plugins do this. + # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated + # content returned by your JSON. + # # If you need to output JSON elsewhere in your HTML, you can just do something # like this, as any unsafe characters (including quotation marks) will be # automatically escaped for you: @@ -217,7 +222,7 @@ module ActiveSupport #:nodoc: end def encode_with(coder) - coder.represent_scalar nil, to_str + coder.represent_object nil, to_str end UNSAFE_STRING_METHODS.each do |unsafe_method| diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 649dc52865..13610ba19f 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -69,7 +69,7 @@ class Time # and minute is passed, then sec, usec and nsec is set to 0. The +options+ # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt> - # <tt>:nsec</tt>. Path either <tt>:usec</tt> or <tt>:nsec</tt>, not both. + # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both. # # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0) # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index e03e7c30d8..664cc15a29 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -373,7 +373,7 @@ module ActiveSupport #:nodoc: # Is the provided constant path defined? def qualified_const_defined?(path) - Object.qualified_const_defined?(path.sub(/^::/, ''), false) + Object.const_defined?(path, false) end # Given +path+, a filesystem path to a ruby file, return an array of @@ -607,7 +607,7 @@ module ActiveSupport #:nodoc: def autoloaded?(desc) return false if desc.is_a?(Module) && desc.anonymous? name = to_constant_name desc - return false unless qualified_const_defined? name + return false unless qualified_const_defined?(name) return autoloaded_constants.include?(name) end diff --git a/activesupport/lib/active_support/i18n_railtie.rb b/activesupport/lib/active_support/i18n_railtie.rb index 9e742b1917..95f3f6255a 100644 --- a/activesupport/lib/active_support/i18n_railtie.rb +++ b/activesupport/lib/active_support/i18n_railtie.rb @@ -68,7 +68,7 @@ module I18n end def self.include_fallbacks_module - I18n.backend.class.send(:include, I18n::Backend::Fallbacks) + I18n.backend.class.include(I18n::Backend::Fallbacks) end def self.init_fallbacks(fallbacks) diff --git a/activesupport/lib/active_support/number_helper.rb b/activesupport/lib/active_support/number_helper.rb index 34439ee8be..cfca42bc69 100644 --- a/activesupport/lib/active_support/number_helper.rb +++ b/activesupport/lib/active_support/number_helper.rb @@ -94,7 +94,7 @@ module ActiveSupport # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:precision</tt> - Sets the precision of the number - # (defaults to 3). + # (defaults to 3). Keeps the number's precision if nil. # * <tt>:significant</tt> - If +true+, precision will be the # # of significant_digits. If +false+, the # of fractional # digits (defaults to +false+). @@ -116,6 +116,7 @@ module ActiveSupport # number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000% # number_to_percentage(302.24398923423, precision: 5) # => 302.24399% # number_to_percentage(1000, locale: :fr) # => 1 000,000% + # number_to_percentage:(1000, precision: nil) # => 1000% # number_to_percentage('98a') # => 98a% # number_to_percentage(100, format: '%n %') # => 100 % def number_to_percentage(number, options = {}) @@ -161,7 +162,7 @@ module ActiveSupport # * <tt>:locale</tt> - Sets the locale to be used for formatting # (defaults to current locale). # * <tt>:precision</tt> - Sets the precision of the number - # (defaults to 3). + # (defaults to 3). Keeps the number's precision if nil. # * <tt>:significant</tt> - If +true+, precision will be the # # of significant_digits. If +false+, the # of fractional # digits (defaults to +false+). @@ -182,6 +183,7 @@ module ActiveSupport # number_to_rounded(111.2345, significant: true) # => 111 # number_to_rounded(111.2345, precision: 1, significant: true) # => 100 # number_to_rounded(13, precision: 5, significant: true) # => 13.000 + # number_to_rounded(13, precision: nil) # => 13 # number_to_rounded(111.234, locale: :fr) # => 111,234 # # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true) 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 dcf9a567e8..df316a08e6 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 @@ -6,36 +6,39 @@ module ActiveSupport def convert precision = options.delete :precision - significant = options.delete :significant - case number - when Float, String - @number = BigDecimal(number.to_s) - when Rational - @number = BigDecimal(number, digit_count(number.to_i) + precision) - 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 = 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 + if precision + case number + when Float, String + @number = BigDecimal(number.to_s) + when Rational + @number = BigDecimal(number, digit_count(number.to_i) + precision) + else + @number = number.to_d + end - formatted_string = - if BigDecimal === rounded_number && rounded_number.finite? - s = rounded_number.to_s('F') + '0'*precision - a, b = s.split('.', 2) - a + '.' + b[0, precision] + if options.delete(: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 - "%00.#{precision}f" % rounded_number + 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 + formatted_string = + if BigDecimal === rounded_number && rounded_number.finite? + s = rounded_number.to_s('F') + '0'*precision + a, b = s.split('.', 2) + a + '.' + b[0, precision] + else + "%00.#{precision}f" % rounded_number + end + else + formatted_string = number + end + delimited_number = NumberToDelimitedConverter.convert(formatted_string, options) format_number(delimited_number) end diff --git a/activesupport/lib/active_support/subscriber.rb b/activesupport/lib/active_support/subscriber.rb index 98be78b41b..cd40284660 100644 --- a/activesupport/lib/active_support/subscriber.rb +++ b/activesupport/lib/active_support/subscriber.rb @@ -96,7 +96,7 @@ module ActiveSupport event.end = finished event.payload.merge!(payload) - method = name.split('.').first + method = name.split('.'.freeze).first send(method, event) end diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb index c7d6c62129..739823bd56 100644 --- a/activesupport/lib/active_support/test_case.rb +++ b/activesupport/lib/active_support/test_case.rb @@ -8,6 +8,7 @@ require 'active_support/testing/declarative' require 'active_support/testing/isolation' require 'active_support/testing/constant_lookup' require 'active_support/testing/time_helpers' +require 'active_support/testing/file_fixtures' require 'active_support/core_ext/kernel/reporting' module ActiveSupport @@ -55,6 +56,7 @@ module ActiveSupport include ActiveSupport::Testing::Assertions include ActiveSupport::Testing::Deprecation include ActiveSupport::Testing::TimeHelpers + include ActiveSupport::Testing::FileFixtures extend ActiveSupport::Testing::Declarative # test/unit backwards compatibility methods diff --git a/activesupport/lib/active_support/testing/file_fixtures.rb b/activesupport/lib/active_support/testing/file_fixtures.rb new file mode 100644 index 0000000000..4c6a0801b8 --- /dev/null +++ b/activesupport/lib/active_support/testing/file_fixtures.rb @@ -0,0 +1,34 @@ +module ActiveSupport + module Testing + # Adds simple access to sample files called file fixtures. + # File fixtures are normal files stored in + # <tt>ActiveSupport::TestCase.file_fixture_path</tt>. + # + # File fixtures are represented as +Pathname+ objects. + # This makes it easy to extract specific information: + # + # file_fixture("example.txt").read # get the file's content + # file_fixture("example.mp3").size # get the file size + module FileFixtures + extend ActiveSupport::Concern + + included do + class_attribute :file_fixture_path, instance_writer: false + end + + # Returns a +Pathname+ to the fixture file named +fixture_name+. + # + # Raises ArgumentError if +fixture_name+ can't be found. + def file_fixture(fixture_name) + path = Pathname.new(File.join(file_fixture_path, fixture_name)) + + if path.exist? + path + else + msg = "the directory '%s' does not contain a file named '%s'" + raise ArgumentError, msg % [file_fixture_path, fixture_name] + end + end + end + end +end diff --git a/activesupport/lib/active_support/testing/stream.rb b/activesupport/lib/active_support/testing/stream.rb new file mode 100644 index 0000000000..895192ad05 --- /dev/null +++ b/activesupport/lib/active_support/testing/stream.rb @@ -0,0 +1,42 @@ +module ActiveSupport + module Testing + module Stream #:nodoc: + private + + def silence_stream(stream) + old_stream = stream.dup + stream.reopen(IO::NULL) + stream.sync = true + yield + ensure + stream.reopen(old_stream) + old_stream.close + end + + def quietly + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end + + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + end + end +end diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb index 8c63815660..df5186ddec 100644 --- a/activesupport/lib/active_support/testing/time_helpers.rb +++ b/activesupport/lib/active_support/testing/time_helpers.rb @@ -99,6 +99,7 @@ module ActiveSupport simple_stubs.stub_object(Time, :now, now) simple_stubs.stub_object(Date, :today, now.to_date) + simple_stubs.stub_object(DateTime, :now, now.to_datetime) if block_given? begin diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 728b53849d..da39f0d245 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -224,13 +224,6 @@ module ActiveSupport @zones ||= zones_map.values.sort end - def zones_map - @zones_map ||= begin - MAPPING.each_key {|place| self[place]} # load all the zones - @lazy_zones_map - end - end - # Locate a specific time zone object. If the argument is a string, it # is interpreted to mean the name of the timezone to locate. If it is a # numeric value it is either the hour offset, or the second offset, of the @@ -257,6 +250,14 @@ module ActiveSupport def us_zones @us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ } end + + private + def zones_map + @zones_map ||= begin + MAPPING.each_key {|place| self[place]} # load all the zones + @lazy_zones_map + end + end end include Comparable diff --git a/activesupport/lib/active_support/xml_mini/libxml.rb b/activesupport/lib/active_support/xml_mini/libxml.rb index 47a2824186..bb0ea9c582 100644 --- a/activesupport/lib/active_support/xml_mini/libxml.rb +++ b/activesupport/lib/active_support/xml_mini/libxml.rb @@ -75,5 +75,5 @@ module LibXML #:nodoc: end end -LibXML::XML::Document.send(:include, LibXML::Conversions::Document) -LibXML::XML::Node.send(:include, LibXML::Conversions::Node) +LibXML::XML::Document.include(LibXML::Conversions::Document) +LibXML::XML::Node.include(LibXML::Conversions::Node) diff --git a/activesupport/lib/active_support/xml_mini/nokogiri.rb b/activesupport/lib/active_support/xml_mini/nokogiri.rb index 7398d4fa82..619cc7522d 100644 --- a/activesupport/lib/active_support/xml_mini/nokogiri.rb +++ b/activesupport/lib/active_support/xml_mini/nokogiri.rb @@ -77,7 +77,7 @@ module ActiveSupport end end - Nokogiri::XML::Document.send(:include, Conversions::Document) - Nokogiri::XML::Node.send(:include, Conversions::Node) + Nokogiri::XML::Document.include(Conversions::Document) + Nokogiri::XML::Node.include(Conversions::Node) end end |