mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-05 23:41:48 +01:00
Vendoring Rails 2.3.5
This commit is contained in:
parent
3e83d19299
commit
f8779795ce
943 changed files with 56503 additions and 61351 deletions
8
vendor/rails/activesupport/lib/active_support/all.rb
vendored
Normal file
8
vendor/rails/activesupport/lib/active_support/all.rb
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# For forward compatibility with Rails 3.
|
||||
#
|
||||
# require 'active_support' loads a very bare minumum in Rails 3.
|
||||
# require 'active_support/all' loads the whole suite like Rails 2 did.
|
||||
#
|
||||
# To prepare for Rails 3, switch to require 'active_support/all' now.
|
||||
|
||||
require 'active_support'
|
||||
72
vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb
vendored
Normal file
72
vendor/rails/activesupport/lib/active_support/backtrace_cleaner.rb
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
module ActiveSupport
|
||||
# Many backtraces include too much information that's not relevant for the context. This makes it hard to find the signal
|
||||
# in the backtrace and adds debugging time. With a BacktraceCleaner, you can setup filters and silencers for your particular
|
||||
# context, so only the relevant lines are included.
|
||||
#
|
||||
# If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always
|
||||
# call BacktraceCleaner#remove_silencers!
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# bc = BacktraceCleaner.new
|
||||
# bc.add_filter { |line| line.gsub(Rails.root, '') }
|
||||
# bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
|
||||
# bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
|
||||
#
|
||||
# Inspired by the Quiet Backtrace gem by Thoughtbot.
|
||||
class BacktraceCleaner
|
||||
def initialize
|
||||
@filters, @silencers = [], []
|
||||
end
|
||||
|
||||
# Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.
|
||||
def clean(backtrace)
|
||||
silence(filter(backtrace))
|
||||
end
|
||||
|
||||
# Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
|
||||
# backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
|
||||
def add_filter(&block)
|
||||
@filters << block
|
||||
end
|
||||
|
||||
# Adds a silencer from the block provided. If the silencer returns true for a given line, it'll be excluded from the
|
||||
# clean backtrace.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
|
||||
# backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
|
||||
def add_silencer(&block)
|
||||
@silencers << block
|
||||
end
|
||||
|
||||
# Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as
|
||||
# you suspect a bug in the libraries you use.
|
||||
def remove_silencers!
|
||||
@silencers = []
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def filter(backtrace)
|
||||
@filters.each do |f|
|
||||
backtrace = backtrace.map { |line| f.call(line) }
|
||||
end
|
||||
|
||||
backtrace
|
||||
end
|
||||
|
||||
def silence(backtrace)
|
||||
@silencers.each do |s|
|
||||
backtrace = backtrace.reject { |line| s.call(line) }
|
||||
end
|
||||
|
||||
backtrace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -13,6 +13,8 @@ module ActiveSupport
|
|||
|
||||
MAX_BUFFER_SIZE = 1000
|
||||
|
||||
##
|
||||
# :singleton-method:
|
||||
# Set to false to disable the silencer
|
||||
cattr_accessor :silencer
|
||||
self.silencer = true
|
||||
|
|
@ -66,13 +68,13 @@ module ActiveSupport
|
|||
|
||||
for severity in Severity.constants
|
||||
class_eval <<-EOT, __FILE__, __LINE__
|
||||
def #{severity.downcase}(message = nil, progname = nil, &block)
|
||||
add(#{severity}, message, progname, &block)
|
||||
end
|
||||
|
||||
def #{severity.downcase}?
|
||||
#{severity} >= @level
|
||||
end
|
||||
def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
|
||||
add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
|
||||
end # end
|
||||
#
|
||||
def #{severity.downcase}? # def debug?
|
||||
#{severity} >= @level # DEBUG >= @level
|
||||
end # end
|
||||
EOT
|
||||
end
|
||||
|
||||
|
|
@ -94,9 +96,12 @@ module ActiveSupport
|
|||
@guard.synchronize do
|
||||
unless buffer.empty?
|
||||
old_buffer = buffer
|
||||
clear_buffer
|
||||
@log.write(old_buffer.join)
|
||||
end
|
||||
|
||||
# Important to do this even if buffer was empty or else @buffer will
|
||||
# accumulate empty arrays for each request where nothing was logged.
|
||||
clear_buffer
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,17 @@ require 'benchmark'
|
|||
module ActiveSupport
|
||||
# See ActiveSupport::Cache::Store for documentation.
|
||||
module Cache
|
||||
autoload :FileStore, 'active_support/cache/file_store'
|
||||
autoload :MemoryStore, 'active_support/cache/memory_store'
|
||||
autoload :SynchronizedMemoryStore, 'active_support/cache/synchronized_memory_store'
|
||||
autoload :DRbStore, 'active_support/cache/drb_store'
|
||||
autoload :MemCacheStore, 'active_support/cache/mem_cache_store'
|
||||
autoload :CompressedMemCacheStore, 'active_support/cache/compressed_mem_cache_store'
|
||||
|
||||
module Strategy
|
||||
autoload :LocalCache, 'active_support/cache/strategy/local_cache'
|
||||
end
|
||||
|
||||
# Creates a new CacheStore object according to the given options.
|
||||
#
|
||||
# If no arguments are passed to this method, then a new
|
||||
|
|
@ -80,11 +91,23 @@ module ActiveSupport
|
|||
class Store
|
||||
cattr_accessor :logger
|
||||
|
||||
attr_reader :silence, :logger_off
|
||||
|
||||
def silence!
|
||||
@silence = true
|
||||
self
|
||||
end
|
||||
|
||||
alias silence? silence
|
||||
alias logger_off? logger_off
|
||||
|
||||
def mute
|
||||
previous_silence, @silence = defined?(@silence) && @silence, true
|
||||
yield
|
||||
ensure
|
||||
@silence = previous_silence
|
||||
end
|
||||
|
||||
# Fetches data from the cache, using the given key. If there is data in
|
||||
# the cache with the given key, then that data is returned.
|
||||
#
|
||||
|
|
@ -136,13 +159,13 @@ module ActiveSupport
|
|||
log("miss", key, options)
|
||||
|
||||
value = nil
|
||||
seconds = Benchmark.realtime { value = yield }
|
||||
ms = Benchmark.ms { value = yield }
|
||||
|
||||
@logger_off = true
|
||||
write(key, value, options)
|
||||
@logger_off = false
|
||||
|
||||
log("write (will save #{'%.2f' % (seconds * 1000)}ms)", key, nil)
|
||||
log('write (will save %.2fms)' % ms, key, nil)
|
||||
|
||||
value
|
||||
end
|
||||
|
|
@ -209,15 +232,17 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
private
|
||||
def expires_in(options)
|
||||
expires_in = options && options[:expires_in]
|
||||
|
||||
raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
|
||||
|
||||
expires_in || 0
|
||||
end
|
||||
|
||||
def log(operation, key, options)
|
||||
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off
|
||||
logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !silence? && !logger_off?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_support/cache/file_store'
|
||||
require 'active_support/cache/memory_store'
|
||||
require 'active_support/cache/drb_store'
|
||||
require 'active_support/cache/mem_cache_store'
|
||||
require 'active_support/cache/compressed_mem_cache_store'
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
require 'drb'
|
||||
|
||||
module ActiveSupport
|
||||
module Cache
|
||||
class DRbStore < MemoryStore #:nodoc:
|
||||
attr_reader :address
|
||||
|
||||
def initialize(address = 'druby://localhost:9192')
|
||||
require 'drb' unless defined?(DRbObject)
|
||||
super()
|
||||
@address = address
|
||||
@data = DRbObject.new(nil, address)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ module ActiveSupport
|
|||
# server goes down, then MemCacheStore will ignore it until it goes back
|
||||
# online.
|
||||
# - Time-based expiry support. See #write and the +:expires_in+ option.
|
||||
# - Per-request in memory cache for all communication with the MemCache server(s).
|
||||
class MemCacheStore < Store
|
||||
module Response # :nodoc:
|
||||
STORED = "STORED\r\n"
|
||||
|
|
@ -22,7 +23,12 @@ module ActiveSupport
|
|||
DELETED = "DELETED\r\n"
|
||||
end
|
||||
|
||||
attr_reader :addresses
|
||||
def self.build_mem_cache(*addresses)
|
||||
addresses = addresses.flatten
|
||||
options = addresses.extract_options!
|
||||
addresses = ["localhost"] if addresses.empty?
|
||||
MemCache.new(addresses, options)
|
||||
end
|
||||
|
||||
# Creates a new MemCacheStore object, with the given memcached server
|
||||
# addresses. Each address is either a host name, or a host-with-port string
|
||||
|
|
@ -32,12 +38,24 @@ module ActiveSupport
|
|||
#
|
||||
# If no addresses are specified, then MemCacheStore will connect to
|
||||
# localhost port 11211 (the default memcached port).
|
||||
#
|
||||
# Instead of addresses one can pass in a MemCache-like object. For example:
|
||||
#
|
||||
# require 'memcached' # gem install memcached; uses C bindings to libmemcached
|
||||
# ActiveSupport::Cache::MemCacheStore.new(Memcached::Rails.new("localhost:11211"))
|
||||
def initialize(*addresses)
|
||||
addresses = addresses.flatten
|
||||
options = addresses.extract_options!
|
||||
addresses = ["localhost"] if addresses.empty?
|
||||
@addresses = addresses
|
||||
@data = MemCache.new(addresses, options)
|
||||
if addresses.first.respond_to?(:get)
|
||||
@data = addresses.first
|
||||
else
|
||||
@data = self.class.build_mem_cache(*addresses)
|
||||
end
|
||||
|
||||
extend Strategy::LocalCache
|
||||
end
|
||||
|
||||
# Reads multiple keys from the cache.
|
||||
def read_multi(*keys)
|
||||
@data.get_multi keys
|
||||
end
|
||||
|
||||
def read(key, options = nil) # :nodoc:
|
||||
|
|
@ -80,6 +98,7 @@ module ActiveSupport
|
|||
def exist?(key, options = nil) # :nodoc:
|
||||
# Doesn't call super, cause exist? in memcache is in fact a read
|
||||
# But who cares? Reading is very fast anyway
|
||||
# Local cache is checked first, if it doesn't know then memcache itself is read from
|
||||
!read(key, options).nil?
|
||||
end
|
||||
|
||||
|
|
@ -94,7 +113,6 @@ module ActiveSupport
|
|||
|
||||
def decrement(key, amount = 1) # :nodoc:
|
||||
log("decrement", key, amount)
|
||||
|
||||
response = @data.decr(key, amount)
|
||||
response == Response::NOT_FOUND ? nil : response
|
||||
rescue MemCache::MemCacheError
|
||||
|
|
@ -102,6 +120,8 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
def delete_matched(matcher, options = nil) # :nodoc:
|
||||
# don't do any local caching at present, just pass
|
||||
# through and let the error happen
|
||||
super
|
||||
raise "Not supported by Memcache"
|
||||
end
|
||||
|
|
@ -115,10 +135,6 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
private
|
||||
def expires_in(options)
|
||||
(options && options[:expires_in]) || 0
|
||||
end
|
||||
|
||||
def raw?(options)
|
||||
options && options[:raw]
|
||||
end
|
||||
|
|
|
|||
104
vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
vendored
Normal file
104
vendor/rails/activesupport/lib/active_support/cache/strategy/local_cache.rb
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
module ActiveSupport
|
||||
module Cache
|
||||
module Strategy
|
||||
module LocalCache
|
||||
# this allows caching of the fact that there is nothing in the remote cache
|
||||
NULL = 'remote_cache_store:null'
|
||||
|
||||
def with_local_cache
|
||||
Thread.current[thread_local_key] = MemoryStore.new
|
||||
yield
|
||||
ensure
|
||||
Thread.current[thread_local_key] = nil
|
||||
end
|
||||
|
||||
def middleware
|
||||
@middleware ||= begin
|
||||
klass = Class.new
|
||||
klass.class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
Thread.current[:#{thread_local_key}] = MemoryStore.new
|
||||
@app.call(env)
|
||||
ensure
|
||||
Thread.current[:#{thread_local_key}] = nil
|
||||
end
|
||||
EOS
|
||||
klass
|
||||
end
|
||||
end
|
||||
|
||||
def read(key, options = nil)
|
||||
value = local_cache && local_cache.read(key)
|
||||
if value == NULL
|
||||
nil
|
||||
elsif value.nil?
|
||||
value = super
|
||||
local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
|
||||
value.duplicable? ? value.dup : value
|
||||
else
|
||||
# forcing the value to be immutable
|
||||
value.duplicable? ? value.dup : value
|
||||
end
|
||||
end
|
||||
|
||||
def write(key, value, options = nil)
|
||||
value = value.to_s if respond_to?(:raw?) && raw?(options)
|
||||
local_cache.mute { local_cache.write(key, value || NULL) } if local_cache
|
||||
super
|
||||
end
|
||||
|
||||
def delete(key, options = nil)
|
||||
local_cache.mute { local_cache.write(key, NULL) } if local_cache
|
||||
super
|
||||
end
|
||||
|
||||
def exist(key, options = nil)
|
||||
value = local_cache.read(key) if local_cache
|
||||
if value == NULL
|
||||
false
|
||||
elsif value
|
||||
true
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def increment(key, amount = 1)
|
||||
if value = super
|
||||
local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
|
||||
value
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def decrement(key, amount = 1)
|
||||
if value = super
|
||||
local_cache.mute { local_cache.write(key, value.to_s) } if local_cache
|
||||
value
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
local_cache.clear if local_cache
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
def thread_local_key
|
||||
@thread_local_key ||= "#{self.class.name.underscore}_local_cache".gsub("/", "_").to_sym
|
||||
end
|
||||
|
||||
def local_cache
|
||||
Thread.current[thread_local_key]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -192,13 +192,8 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
def should_run_callback?(*args)
|
||||
if options[:if]
|
||||
evaluate_method(options[:if], *args)
|
||||
elsif options[:unless]
|
||||
!evaluate_method(options[:unless], *args)
|
||||
else
|
||||
true
|
||||
end
|
||||
[options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
|
||||
![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -210,20 +205,24 @@ module ActiveSupport
|
|||
def define_callbacks(*callbacks)
|
||||
callbacks.each do |callback|
|
||||
class_eval <<-"end_eval"
|
||||
def self.#{callback}(*methods, &block)
|
||||
callbacks = CallbackChain.build(:#{callback}, *methods, &block)
|
||||
(@#{callback}_callbacks ||= CallbackChain.new).concat callbacks
|
||||
end
|
||||
|
||||
def self.#{callback}_callback_chain
|
||||
@#{callback}_callbacks ||= CallbackChain.new
|
||||
|
||||
if superclass.respond_to?(:#{callback}_callback_chain)
|
||||
CallbackChain.new(superclass.#{callback}_callback_chain + @#{callback}_callbacks)
|
||||
else
|
||||
@#{callback}_callbacks
|
||||
end
|
||||
end
|
||||
def self.#{callback}(*methods, &block) # def self.before_save(*methods, &block)
|
||||
callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:before_save, *methods, &block)
|
||||
@#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new
|
||||
@#{callback}_callbacks.concat callbacks # @before_save_callbacks.concat callbacks
|
||||
end # end
|
||||
#
|
||||
def self.#{callback}_callback_chain # def self.before_save_callback_chain
|
||||
@#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new
|
||||
#
|
||||
if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:before_save_callback_chain)
|
||||
CallbackChain.new( # CallbackChain.new(
|
||||
superclass.#{callback}_callback_chain + # superclass.before_save_callback_chain +
|
||||
@#{callback}_callbacks # @before_save_callbacks
|
||||
) # )
|
||||
else # else
|
||||
@#{callback}_callbacks # @before_save_callbacks
|
||||
end # end
|
||||
end # end
|
||||
end_eval
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].sort.each do |path|
|
||||
filename = File.basename(path)
|
||||
require "active_support/core_ext/#{filename}"
|
||||
filenames = Dir["#{File.dirname(__FILE__)}/core_ext/*.rb"].sort.map do |path|
|
||||
File.basename(path, '.rb')
|
||||
end
|
||||
|
||||
# deprecated
|
||||
filenames -= %w(blank)
|
||||
|
||||
filenames.each { |filename| require "active_support/core_ext/#{filename}" }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ require 'active_support/core_ext/array/conversions'
|
|||
require 'active_support/core_ext/array/extract_options'
|
||||
require 'active_support/core_ext/array/grouping'
|
||||
require 'active_support/core_ext/array/random_access'
|
||||
require 'active_support/core_ext/array/wrapper'
|
||||
|
||||
class Array #:nodoc:
|
||||
include ActiveSupport::CoreExtensions::Array::Access
|
||||
|
|
@ -10,4 +11,5 @@ class Array #:nodoc:
|
|||
include ActiveSupport::CoreExtensions::Array::ExtractOptions
|
||||
include ActiveSupport::CoreExtensions::Array::Grouping
|
||||
include ActiveSupport::CoreExtensions::Array::RandomAccess
|
||||
extend ActiveSupport::CoreExtensions::Array::Wrapper
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,29 +1,41 @@
|
|||
require 'builder'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Array #:nodoc:
|
||||
module Conversions
|
||||
# Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
|
||||
# * <tt>:connector</tt> - The word used to join the last element in arrays with two or more elements (default: "and")
|
||||
# * <tt>:skip_last_comma</tt> - Set to true to return "a, b and c" instead of "a, b, and c".
|
||||
def to_sentence(options = {})
|
||||
options.assert_valid_keys(:connector, :skip_last_comma, :locale)
|
||||
|
||||
default = I18n.translate(:'support.array.sentence_connector', :locale => options[:locale])
|
||||
default_skip_last_comma = I18n.translate(:'support.array.skip_last_comma', :locale => options[:locale])
|
||||
options.reverse_merge! :connector => default, :skip_last_comma => default_skip_last_comma
|
||||
options[:connector] = "#{options[:connector]} " unless options[:connector].nil? || options[:connector].strip == ''
|
||||
# * <tt>:words_connector</tt> - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
|
||||
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements in arrays with two elements (default: " and ")
|
||||
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")
|
||||
def to_sentence(options = {})
|
||||
default_words_connector = I18n.translate(:'support.array.words_connector', :locale => options[:locale])
|
||||
default_two_words_connector = I18n.translate(:'support.array.two_words_connector', :locale => options[:locale])
|
||||
default_last_word_connector = I18n.translate(:'support.array.last_word_connector', :locale => options[:locale])
|
||||
|
||||
# Try to emulate to_senteces previous to 2.3
|
||||
if options.has_key?(:connector) || options.has_key?(:skip_last_comma)
|
||||
::ActiveSupport::Deprecation.warn(":connector has been deprecated. Use :words_connector instead", caller) if options.has_key? :connector
|
||||
::ActiveSupport::Deprecation.warn(":skip_last_comma has been deprecated. Use :last_word_connector instead", caller) if options.has_key? :skip_last_comma
|
||||
|
||||
skip_last_comma = options.delete :skip_last_comma
|
||||
if connector = options.delete(:connector)
|
||||
options[:last_word_connector] ||= skip_last_comma ? connector : ", #{connector}"
|
||||
else
|
||||
options[:last_word_connector] ||= skip_last_comma ? default_two_words_connector : default_last_word_connector
|
||||
end
|
||||
end
|
||||
|
||||
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
||||
options.reverse_merge! :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector
|
||||
|
||||
case length
|
||||
when 0
|
||||
""
|
||||
when 1
|
||||
self[0].to_s
|
||||
when 2
|
||||
"#{self[0]} #{options[:connector]}#{self[1]}"
|
||||
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
||||
else
|
||||
"#{self[0...-1].join(', ')}#{options[:skip_last_comma] ? '' : ','} #{options[:connector]}#{self[-1]}"
|
||||
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -149,7 +161,9 @@ module ActiveSupport #:nodoc:
|
|||
#
|
||||
def to_xml(options = {})
|
||||
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
||||
require 'builder' unless defined?(Builder)
|
||||
|
||||
options = options.dup
|
||||
options[:root] ||= all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ? first.class.to_s.underscore.pluralize : "records"
|
||||
options[:children] ||= options[:root].singularize
|
||||
options[:indent] ||= 2
|
||||
|
|
|
|||
24
vendor/rails/activesupport/lib/active_support/core_ext/array/wrapper.rb
vendored
Normal file
24
vendor/rails/activesupport/lib/active_support/core_ext/array/wrapper.rb
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Array #:nodoc:
|
||||
module Wrapper
|
||||
# Wraps the object in an Array unless it's an Array. Converts the
|
||||
# object to an Array using #to_ary if it implements that.
|
||||
def wrap(object)
|
||||
case object
|
||||
when nil
|
||||
[]
|
||||
when self
|
||||
object
|
||||
else
|
||||
if object.respond_to?(:to_ary)
|
||||
object.to_ary
|
||||
else
|
||||
[object]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,12 +1,19 @@
|
|||
require 'benchmark'
|
||||
|
||||
class << Benchmark
|
||||
remove_method :realtime
|
||||
# Earlier Ruby had a slower implementation.
|
||||
if RUBY_VERSION < '1.8.7'
|
||||
remove_method :realtime
|
||||
|
||||
def realtime
|
||||
r0 = Time.now
|
||||
yield
|
||||
r1 = Time.now
|
||||
r1.to_f - r0.to_f
|
||||
def realtime
|
||||
r0 = Time.now
|
||||
yield
|
||||
r1 = Time.now
|
||||
r1.to_f - r0.to_f
|
||||
end
|
||||
end
|
||||
|
||||
def ms
|
||||
1000 * realtime { yield }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,58 +1,2 @@
|
|||
class Object
|
||||
# An object is blank if it's false, empty, or a whitespace string.
|
||||
# For example, "", " ", +nil+, [], and {} are blank.
|
||||
#
|
||||
# This simplifies
|
||||
#
|
||||
# if !address.nil? && !address.empty?
|
||||
#
|
||||
# to
|
||||
#
|
||||
# if !address.blank?
|
||||
def blank?
|
||||
respond_to?(:empty?) ? empty? : !self
|
||||
end
|
||||
|
||||
# An object is present if it's not blank.
|
||||
def present?
|
||||
!blank?
|
||||
end
|
||||
end
|
||||
|
||||
class NilClass #:nodoc:
|
||||
def blank?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class FalseClass #:nodoc:
|
||||
def blank?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class TrueClass #:nodoc:
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
class Array #:nodoc:
|
||||
alias_method :blank?, :empty?
|
||||
end
|
||||
|
||||
class Hash #:nodoc:
|
||||
alias_method :blank?, :empty?
|
||||
end
|
||||
|
||||
class String #:nodoc:
|
||||
def blank?
|
||||
self !~ /\S/
|
||||
end
|
||||
end
|
||||
|
||||
class Numeric #:nodoc:
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
end
|
||||
require 'active_support/core_ext/object/blank'
|
||||
ActiveSupport::Deprecation.warn 'require "active_support/core_ext/blank" is deprecated and will be removed in Rails 3. Use require "active_support/core_ext/object/blank" instead.'
|
||||
|
|
|
|||
|
|
@ -2,11 +2,20 @@ module ActiveSupport #:nodoc:
|
|||
module CoreExtensions #:nodoc:
|
||||
module CGI #:nodoc:
|
||||
module EscapeSkippingSlashes #:nodoc:
|
||||
def escape_skipping_slashes(str)
|
||||
str = str.join('/') if str.respond_to? :join
|
||||
str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
|
||||
"%#{$1.unpack('H2').first.upcase}"
|
||||
end.tr(' ', '+')
|
||||
if RUBY_VERSION >= '1.9'
|
||||
def escape_skipping_slashes(str)
|
||||
str = str.join('/') if str.respond_to? :join
|
||||
str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
|
||||
"%#{$1.unpack('H2' * $1.bytesize).join('%').upcase}"
|
||||
end.tr(' ', '+')
|
||||
end
|
||||
else
|
||||
def escape_skipping_slashes(str)
|
||||
str = str.join('/') if str.respond_to? :join
|
||||
str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
|
||||
"%#{$1.unpack('H2').first.upcase}"
|
||||
end.tr(' ', '+')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,17 +11,17 @@ class Class
|
|||
syms.flatten.each do |sym|
|
||||
next if sym.is_a?(Hash)
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
unless defined? @@#{sym}
|
||||
@@#{sym} = nil
|
||||
end
|
||||
|
||||
def self.#{sym}
|
||||
@@#{sym}
|
||||
end
|
||||
|
||||
def #{sym}
|
||||
@@#{sym}
|
||||
end
|
||||
unless defined? @@#{sym} # unless defined? @@hair_colors
|
||||
@@#{sym} = nil # @@hair_colors = nil
|
||||
end # end
|
||||
#
|
||||
def self.#{sym} # def self.hair_colors
|
||||
@@#{sym} # @@hair_colors
|
||||
end # end
|
||||
#
|
||||
def #{sym} # def hair_colors
|
||||
@@#{sym} # @@hair_colors
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -30,19 +30,19 @@ class Class
|
|||
options = syms.extract_options!
|
||||
syms.flatten.each do |sym|
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
unless defined? @@#{sym}
|
||||
@@#{sym} = nil
|
||||
end
|
||||
|
||||
def self.#{sym}=(obj)
|
||||
@@#{sym} = obj
|
||||
end
|
||||
|
||||
#{"
|
||||
def #{sym}=(obj)
|
||||
@@#{sym} = obj
|
||||
end
|
||||
" unless options[:instance_writer] == false }
|
||||
unless defined? @@#{sym} # unless defined? @@hair_colors
|
||||
@@#{sym} = nil # @@hair_colors = nil
|
||||
end # end
|
||||
#
|
||||
def self.#{sym}=(obj) # def self.hair_colors=(obj)
|
||||
@@#{sym} = obj # @@hair_colors = obj
|
||||
end # end
|
||||
#
|
||||
#{" #
|
||||
def #{sym}=(obj) # def hair_colors=(obj)
|
||||
@@#{sym} = obj # @@hair_colors = obj
|
||||
end # end
|
||||
" unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,22 +9,23 @@ class Class
|
|||
class_name_to_stop_searching_on = self.superclass.name.blank? ? "Object" : self.superclass.name
|
||||
names.each do |name|
|
||||
class_eval <<-EOS
|
||||
def self.#{name}
|
||||
if defined?(@#{name})
|
||||
@#{name}
|
||||
elsif superclass < #{class_name_to_stop_searching_on} && superclass.respond_to?(:#{name})
|
||||
superclass.#{name}
|
||||
end
|
||||
end
|
||||
def #{name}
|
||||
self.class.#{name}
|
||||
end
|
||||
def self.#{name}?
|
||||
!!#{name}
|
||||
end
|
||||
def #{name}?
|
||||
!!#{name}
|
||||
end
|
||||
def self.#{name} # def self.only_reader
|
||||
if defined?(@#{name}) # if defined?(@only_reader)
|
||||
@#{name} # @only_reader
|
||||
elsif superclass < #{class_name_to_stop_searching_on} && # elsif superclass < Object &&
|
||||
superclass.respond_to?(:#{name}) # superclass.respond_to?(:only_reader)
|
||||
superclass.#{name} # superclass.only_reader
|
||||
end # end
|
||||
end # end
|
||||
def #{name} # def only_reader
|
||||
self.class.#{name} # self.class.only_reader
|
||||
end # end
|
||||
def self.#{name}? # def self.only_reader?
|
||||
!!#{name} # !!only_reader
|
||||
end # end
|
||||
def #{name}? # def only_reader?
|
||||
!!#{name} # !!only_reader
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -32,9 +33,9 @@ class Class
|
|||
def superclass_delegating_writer(*names)
|
||||
names.each do |name|
|
||||
class_eval <<-EOS
|
||||
def self.#{name}=(value)
|
||||
@#{name} = value
|
||||
end
|
||||
def self.#{name}=(value) # def self.only_writer=(value)
|
||||
@#{name} = value # @only_writer = value
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ class Class # :nodoc:
|
|||
syms.each do |sym|
|
||||
next if sym.is_a?(Hash)
|
||||
class_eval <<-EOS
|
||||
def self.#{sym}
|
||||
read_inheritable_attribute(:#{sym})
|
||||
end
|
||||
|
||||
def #{sym}
|
||||
self.class.#{sym}
|
||||
end
|
||||
def self.#{sym} # def self.before_add_for_comments
|
||||
read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:before_add_for_comments)
|
||||
end # end
|
||||
#
|
||||
def #{sym} # def before_add_for_comments
|
||||
self.class.#{sym} # self.class.before_add_for_comments
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -26,15 +26,15 @@ class Class # :nodoc:
|
|||
options = syms.extract_options!
|
||||
syms.each do |sym|
|
||||
class_eval <<-EOS
|
||||
def self.#{sym}=(obj)
|
||||
write_inheritable_attribute(:#{sym}, obj)
|
||||
end
|
||||
|
||||
#{"
|
||||
def #{sym}=(obj)
|
||||
self.class.#{sym} = obj
|
||||
end
|
||||
" unless options[:instance_writer] == false }
|
||||
def self.#{sym}=(obj) # def self.color=(obj)
|
||||
write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:color, obj)
|
||||
end # end
|
||||
#
|
||||
#{" #
|
||||
def #{sym}=(obj) # def color=(obj)
|
||||
self.class.#{sym} = obj # self.class.color = obj
|
||||
end # end
|
||||
" unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -43,15 +43,15 @@ class Class # :nodoc:
|
|||
options = syms.extract_options!
|
||||
syms.each do |sym|
|
||||
class_eval <<-EOS
|
||||
def self.#{sym}=(obj)
|
||||
write_inheritable_array(:#{sym}, obj)
|
||||
end
|
||||
|
||||
#{"
|
||||
def #{sym}=(obj)
|
||||
self.class.#{sym} = obj
|
||||
end
|
||||
" unless options[:instance_writer] == false }
|
||||
def self.#{sym}=(obj) # def self.levels=(obj)
|
||||
write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:levels, obj)
|
||||
end # end
|
||||
#
|
||||
#{" #
|
||||
def #{sym}=(obj) # def levels=(obj)
|
||||
self.class.#{sym} = obj # self.class.levels = obj
|
||||
end # end
|
||||
" unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -60,15 +60,15 @@ class Class # :nodoc:
|
|||
options = syms.extract_options!
|
||||
syms.each do |sym|
|
||||
class_eval <<-EOS
|
||||
def self.#{sym}=(obj)
|
||||
write_inheritable_hash(:#{sym}, obj)
|
||||
end
|
||||
|
||||
#{"
|
||||
def #{sym}=(obj)
|
||||
self.class.#{sym} = obj
|
||||
end
|
||||
" unless options[:instance_writer] == false }
|
||||
def self.#{sym}=(obj) # def self.nicknames=(obj)
|
||||
write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:nicknames, obj)
|
||||
end # end
|
||||
#
|
||||
#{" #
|
||||
def #{sym}=(obj) # def nicknames=(obj)
|
||||
self.class.#{sym} = obj # self.class.nicknames = obj
|
||||
end # end
|
||||
" unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module Date #:nodoc:
|
||||
# Enables the use of time calculations within Time itself
|
||||
# Enables the use of time calculations within Date itself
|
||||
module Calculations
|
||||
def self.included(base) #:nodoc:
|
||||
base.extend ClassMethods
|
||||
|
|
@ -92,6 +92,7 @@ module ActiveSupport #:nodoc:
|
|||
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
|
||||
# any of these keys: <tt>:years</tt>, <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>.
|
||||
def advance(options)
|
||||
options = options.dup
|
||||
d = self
|
||||
d = d >> options.delete(:years) * 12 if options[:years]
|
||||
d = d >> options.delete(:months) if options[:months]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ module ActiveSupport #:nodoc:
|
|||
#
|
||||
# This method is aliased to <tt>to_s</tt>.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ==== Examples
|
||||
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
||||
#
|
||||
# date.to_formatted_s(:db) # => "2007-11-10"
|
||||
|
|
@ -76,7 +76,7 @@ module ActiveSupport #:nodoc:
|
|||
# Converts a Date instance to a Time, where the time is set to the beginning of the day.
|
||||
# The timezone can be either :local or :utc (default :local).
|
||||
#
|
||||
# ==== Examples:
|
||||
# ==== Examples
|
||||
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
||||
#
|
||||
# date.to_time # => Sat Nov 10 00:00:00 0800 2007
|
||||
|
|
@ -90,7 +90,7 @@ module ActiveSupport #:nodoc:
|
|||
# Converts a Date instance to a DateTime, where the time is set to the beginning of the day
|
||||
# and UTC offset is set to 0.
|
||||
#
|
||||
# ==== Example:
|
||||
# ==== Examples
|
||||
# date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007
|
||||
#
|
||||
# date.to_datetime # => Sat, 10 Nov 2007 00:00:00 0000
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ module ActiveSupport #:nodoc:
|
|||
#
|
||||
# This method is aliased to <tt>to_s</tt>.
|
||||
#
|
||||
# === Examples:
|
||||
# === 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"
|
||||
|
|
|
|||
|
|
@ -55,12 +55,10 @@ module Enumerable
|
|||
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
|
||||
#
|
||||
def sum(identity = 0, &block)
|
||||
return identity unless size > 0
|
||||
|
||||
if block_given?
|
||||
map(&block).sum
|
||||
map(&block).sum(identity)
|
||||
else
|
||||
inject { |sum, element| sum + element }
|
||||
inject { |sum, element| sum + element } || identity
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -104,4 +102,13 @@ module Enumerable
|
|||
size = block_given? ? select(&block).size : self.size
|
||||
size > 1
|
||||
end
|
||||
|
||||
# Returns true if none of the elements match the given block.
|
||||
#
|
||||
# success = responses.none? {|r| r.status / 100 == 5 }
|
||||
#
|
||||
# This is a builtin method in Ruby 1.8.7 and later.
|
||||
def none?(&block)
|
||||
!any?(&block)
|
||||
end unless [].respond_to?(:none?)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,14 +6,16 @@ module ActiveSupport
|
|||
end
|
||||
end
|
||||
|
||||
# TODO: Turn all this into using the BacktraceCleaner.
|
||||
class Exception # :nodoc:
|
||||
def clean_message
|
||||
Pathname.clean_within message
|
||||
end
|
||||
|
||||
|
||||
TraceSubstitutions = []
|
||||
FrameworkRegexp = /generated|vendor|dispatch|ruby|script\/\w+/
|
||||
|
||||
FrameworkStart = /action_controller\/dispatcher\.rb/.freeze
|
||||
FrameworkRegexp = /generated|vendor|dispatch|ruby|script\/\w+/.freeze
|
||||
|
||||
def clean_backtrace
|
||||
backtrace.collect do |line|
|
||||
Pathname.clean_within(TraceSubstitutions.inject(line) do |result, (regexp, sub)|
|
||||
|
|
@ -21,20 +23,22 @@ class Exception # :nodoc:
|
|||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def application_backtrace
|
||||
before_framework_frame = nil
|
||||
before_application_frame = true
|
||||
|
||||
|
||||
trace = clean_backtrace.reject do |line|
|
||||
before_framework_frame ||= (line =~ FrameworkStart)
|
||||
non_app_frame = (line =~ FrameworkRegexp)
|
||||
before_application_frame = false unless non_app_frame
|
||||
non_app_frame && ! before_application_frame
|
||||
before_framework_frame || (non_app_frame && !before_application_frame)
|
||||
end
|
||||
|
||||
|
||||
# If we didn't find any application frames, return an empty app trace.
|
||||
before_application_frame ? [] : trace
|
||||
end
|
||||
|
||||
|
||||
def framework_backtrace
|
||||
clean_backtrace.grep FrameworkRegexp
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
require 'tempfile'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module File #:nodoc:
|
||||
|
|
@ -18,6 +16,8 @@ module ActiveSupport #:nodoc:
|
|||
# file.write("hello")
|
||||
# end
|
||||
def atomic_write(file_name, temp_dir = Dir.tmpdir)
|
||||
require 'tempfile' unless defined?(Tempfile)
|
||||
|
||||
temp_file = Tempfile.new(basename(file_name), temp_dir)
|
||||
yield temp_file
|
||||
temp_file.close
|
||||
|
|
@ -27,7 +27,7 @@ module ActiveSupport #:nodoc:
|
|||
old_stat = stat(file_name)
|
||||
rescue Errno::ENOENT
|
||||
# No old permissions, write a temp file to determine the defaults
|
||||
check_name = ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}"
|
||||
check_name = join(dirname(file_name), ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}")
|
||||
open(check_name, "w") { }
|
||||
old_stat = stat(check_name)
|
||||
unlink(check_name)
|
||||
|
|
|
|||
|
|
@ -1,47 +1,30 @@
|
|||
require 'date'
|
||||
require 'cgi'
|
||||
require 'builder'
|
||||
require 'xmlsimple'
|
||||
|
||||
# Locked down XmlSimple#xml_in_string
|
||||
class XmlSimple
|
||||
# Same as xml_in but doesn't try to smartly shoot itself in the foot.
|
||||
def xml_in_string(string, options = nil)
|
||||
handle_options('in', options)
|
||||
|
||||
@doc = parse(string)
|
||||
result = collapse(@doc.root)
|
||||
|
||||
if @options['keeproot']
|
||||
merge({}, @doc.root.name, result)
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def self.xml_in_string(string, options = nil)
|
||||
new.xml_in_string(string, options)
|
||||
end
|
||||
end
|
||||
|
||||
# This module exists to decorate files deserialized using Hash.from_xml with
|
||||
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
||||
module FileLike #:nodoc:
|
||||
attr_writer :original_filename, :content_type
|
||||
|
||||
def original_filename
|
||||
@original_filename || 'untitled'
|
||||
end
|
||||
|
||||
def content_type
|
||||
@content_type || 'application/octet-stream'
|
||||
end
|
||||
end
|
||||
require 'active_support/core_ext/module/attribute_accessors'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
# these accessors are here because people using ActiveResource and REST to integrate with other systems
|
||||
# have to be able to control the default behavior of rename_key. dasherize_xml is set to true to emulate
|
||||
# existing behavior. In a future version it should be set to false by default.
|
||||
mattr_accessor :dasherize_xml
|
||||
mattr_accessor :camelize_xml
|
||||
self.dasherize_xml = true
|
||||
self.camelize_xml = false
|
||||
module CoreExtensions #:nodoc:
|
||||
module Hash #:nodoc:
|
||||
module Conversions
|
||||
# This module exists to decorate files deserialized using Hash.from_xml with
|
||||
# the <tt>original_filename</tt> and <tt>content_type</tt> methods.
|
||||
module FileLike #:nodoc:
|
||||
attr_writer :original_filename, :content_type
|
||||
|
||||
def original_filename
|
||||
@original_filename || 'untitled'
|
||||
end
|
||||
|
||||
def content_type
|
||||
@content_type || 'application/octet-stream'
|
||||
end
|
||||
end
|
||||
|
||||
XML_TYPE_NAMES = {
|
||||
"Symbol" => "symbol",
|
||||
|
|
@ -49,11 +32,12 @@ module ActiveSupport #:nodoc:
|
|||
"Bignum" => "integer",
|
||||
"BigDecimal" => "decimal",
|
||||
"Float" => "float",
|
||||
"TrueClass" => "boolean",
|
||||
"FalseClass" => "boolean",
|
||||
"Date" => "date",
|
||||
"DateTime" => "datetime",
|
||||
"Time" => "datetime",
|
||||
"TrueClass" => "boolean",
|
||||
"FalseClass" => "boolean"
|
||||
"ActiveSupport::TimeWithZone" => "datetime"
|
||||
} unless defined?(XML_TYPE_NAMES)
|
||||
|
||||
XML_FORMATTING = {
|
||||
|
|
@ -100,7 +84,7 @@ module ActiveSupport #:nodoc:
|
|||
# Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
|
||||
# passed to enclose the param names (see example below).
|
||||
#
|
||||
# ==== Example:
|
||||
# ==== Examples
|
||||
# { :name => 'David', :nationality => 'Danish' }.to_query # => "name=David&nationality=Danish"
|
||||
#
|
||||
# { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
||||
|
|
@ -113,12 +97,14 @@ module ActiveSupport #:nodoc:
|
|||
alias_method :to_param, :to_query
|
||||
|
||||
def to_xml(options = {})
|
||||
require 'builder' unless defined?(Builder)
|
||||
|
||||
options = options.dup
|
||||
options[:indent] ||= 2
|
||||
options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
|
||||
:root => "hash" })
|
||||
options[:builder].instruct! unless options.delete(:skip_instruct)
|
||||
dasherize = !options.has_key?(:dasherize) || options[:dasherize]
|
||||
root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
|
||||
root = rename_key(options[:root].to_s, options)
|
||||
|
||||
options[:builder].__send__(:method_missing, root) do
|
||||
each do |key, value|
|
||||
|
|
@ -145,7 +131,7 @@ module ActiveSupport #:nodoc:
|
|||
else
|
||||
type_name = XML_TYPE_NAMES[value.class.name]
|
||||
|
||||
key = dasherize ? key.to_s.dasherize : key.to_s
|
||||
key = rename_key(key.to_s, options)
|
||||
|
||||
attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
|
||||
if value.nil?
|
||||
|
|
@ -165,15 +151,17 @@ module ActiveSupport #:nodoc:
|
|||
|
||||
end
|
||||
|
||||
def rename_key(key, options = {})
|
||||
camelize = options.has_key?(:camelize) ? options[:camelize] : ActiveSupport.camelize_xml
|
||||
dasherize = options.has_key?(:dasherize) ? options[:dasherize] : ActiveSupport.dasherize_xml
|
||||
key = key.camelize if camelize
|
||||
key = key.dasherize if dasherize
|
||||
key
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def from_xml(xml)
|
||||
# TODO: Refactor this into something much cleaner that doesn't rely on XmlSimple
|
||||
typecast_xml_value(undasherize_keys(XmlSimple.xml_in_string(xml,
|
||||
'forcearray' => false,
|
||||
'forcecontent' => true,
|
||||
'keeproot' => true,
|
||||
'contentkey' => '__content__')
|
||||
))
|
||||
typecast_xml_value(unrename_keys(XmlMini.parse(xml)))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -239,15 +227,15 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
def undasherize_keys(params)
|
||||
def unrename_keys(params)
|
||||
case params.class.to_s
|
||||
when "Hash"
|
||||
params.inject({}) do |h,(k,v)|
|
||||
h[k.to_s.tr("-", "_")] = undasherize_keys(v)
|
||||
h[k.to_s.tr("-", "_")] = unrename_keys(v)
|
||||
h
|
||||
end
|
||||
when "Array"
|
||||
params.map { |v| undasherize_keys(v) }
|
||||
params.map { |v| unrename_keys(v) }
|
||||
else
|
||||
params
|
||||
end
|
||||
|
|
|
|||
|
|
@ -91,6 +91,12 @@ class HashWithIndifferentAccess < Hash
|
|||
self.dup.update(hash)
|
||||
end
|
||||
|
||||
# Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
|
||||
# This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
|
||||
def reverse_merge(other_hash)
|
||||
super other_hash.with_indifferent_access
|
||||
end
|
||||
|
||||
# Removes a specified key from the hash.
|
||||
def delete(key)
|
||||
super(convert_key(key))
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ module ActiveSupport #:nodoc:
|
|||
# Note that keys are NOT treated indifferently, meaning if you use strings for keys but assert symbols
|
||||
# as keys, this will fail.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ==== Examples
|
||||
# { :name => "Rob", :years => "28" }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key(s): years"
|
||||
# { :name => "Rob", :age => "28" }.assert_valid_keys("name", "age") # => raises "ArgumentError: Unknown key(s): name, age"
|
||||
# { :name => "Rob", :age => "28" }.assert_valid_keys(:name, :age) # => passes, raises nothing
|
||||
|
|
|
|||
|
|
@ -24,10 +24,17 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
|
||||
# Replaces the hash with only the given keys.
|
||||
# Returns a hash contained the removed key/value pairs
|
||||
# {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4}
|
||||
def slice!(*keys)
|
||||
replace(slice(*keys))
|
||||
keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
|
||||
omit = slice(*self.keys - keys)
|
||||
hash = slice(*keys)
|
||||
replace(hash)
|
||||
omit
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,15 @@ module Kernel
|
|||
unless respond_to?(:debugger)
|
||||
# Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it).
|
||||
def debugger
|
||||
Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
|
||||
message = "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
|
||||
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
||||
end
|
||||
end
|
||||
|
||||
undef :breakpoint if respond_to?(:breakpoint)
|
||||
def breakpoint
|
||||
Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
|
||||
message = "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
|
||||
defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
|
||||
debugger
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
class Logger
|
||||
def self.define_around_helper(level)
|
||||
module_eval <<-end_eval
|
||||
def around_#{level}(before_message, after_message, &block)
|
||||
self.#{level}(before_message)
|
||||
return_value = block.call(self)
|
||||
self.#{level}(after_message)
|
||||
return return_value
|
||||
end
|
||||
def around_#{level}(before_message, after_message, &block) # def around_debug(before_message, after_message, &block)
|
||||
self.#{level}(before_message) # self.debug(before_message)
|
||||
return_value = block.call(self) # return_value = block.call(self)
|
||||
self.#{level}(after_message) # self.debug(after_message)
|
||||
return return_value # return return_value
|
||||
end # end
|
||||
end_eval
|
||||
end
|
||||
[:debug, :info, :error, :fatal].each {|level| define_around_helper(level) }
|
||||
|
|
@ -30,6 +30,8 @@ require 'logger'
|
|||
#
|
||||
# Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
|
||||
class Logger
|
||||
##
|
||||
# :singleton-method:
|
||||
# Set to false to disable the silencer
|
||||
cattr_accessor :silencer
|
||||
self.silencer = true
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ module ActiveSupport
|
|||
# e.title # => "Megastars"
|
||||
def alias_attribute(new_name, old_name)
|
||||
module_eval <<-STR, __FILE__, __LINE__+1
|
||||
def #{new_name}; self.#{old_name}; end
|
||||
def #{new_name}?; self.#{old_name}?; end
|
||||
def #{new_name}=(v); self.#{old_name} = v; end
|
||||
def #{new_name}; self.#{old_name}; end # def subject; self.title; end
|
||||
def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
|
||||
def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
|
||||
STR
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ class Module
|
|||
raise 'Default value or block required' unless !default.nil? || block
|
||||
define_method(sym, block_given? ? block : Proc.new { default })
|
||||
module_eval(<<-EVAL, __FILE__, __LINE__)
|
||||
def #{sym}=(value)
|
||||
class << self; attr_reader :#{sym} end
|
||||
@#{sym} = value
|
||||
end
|
||||
def #{sym}=(value) # def age=(value)
|
||||
class << self; attr_reader :#{sym} end # class << self; attr_reader :age end
|
||||
@#{sym} = value # @age = value
|
||||
end # end
|
||||
EVAL
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
require "active_support/core_ext/array"
|
||||
|
||||
# Extends the module object with module and instance accessors for class attributes,
|
||||
# just like the native attr* accessors for instance attributes.
|
||||
#
|
||||
|
|
@ -15,17 +17,17 @@ class Module
|
|||
syms.each do |sym|
|
||||
next if sym.is_a?(Hash)
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
unless defined? @@#{sym}
|
||||
@@#{sym} = nil
|
||||
end
|
||||
|
||||
def self.#{sym}
|
||||
@@#{sym}
|
||||
end
|
||||
|
||||
def #{sym}
|
||||
@@#{sym}
|
||||
end
|
||||
unless defined? @@#{sym} # unless defined? @@pagination_options
|
||||
@@#{sym} = nil # @@pagination_options = nil
|
||||
end # end
|
||||
#
|
||||
def self.#{sym} # def self.pagination_options
|
||||
@@#{sym} # @@pagination_options
|
||||
end # end
|
||||
#
|
||||
def #{sym} # def pagination_options
|
||||
@@#{sym} # @@pagination_options
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -34,19 +36,19 @@ class Module
|
|||
options = syms.extract_options!
|
||||
syms.each do |sym|
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
unless defined? @@#{sym}
|
||||
@@#{sym} = nil
|
||||
end
|
||||
|
||||
def self.#{sym}=(obj)
|
||||
@@#{sym} = obj
|
||||
end
|
||||
|
||||
#{"
|
||||
def #{sym}=(obj)
|
||||
@@#{sym} = obj
|
||||
end
|
||||
" unless options[:instance_writer] == false }
|
||||
unless defined? @@#{sym} # unless defined? @@pagination_options
|
||||
@@#{sym} = nil # @@pagination_options = nil
|
||||
end # end
|
||||
#
|
||||
def self.#{sym}=(obj) # def self.pagination_options=(obj)
|
||||
@@#{sym} = obj # @@pagination_options = obj
|
||||
end # end
|
||||
#
|
||||
#{" #
|
||||
def #{sym}=(obj) # def pagination_options=(obj)
|
||||
@@#{sym} = obj # @@pagination_options = obj
|
||||
end # end
|
||||
" unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -72,6 +72,30 @@ class Module
|
|||
# invoice.customer_name # => "John Doe"
|
||||
# invoice.customer_address # => "Vimmersvej 13"
|
||||
#
|
||||
# If the object to which you delegate can be nil, you may want to use the
|
||||
# :allow_nil option. In that case, it returns nil instead of raising a
|
||||
# NoMethodError exception:
|
||||
#
|
||||
# class Foo
|
||||
# attr_accessor :bar
|
||||
# def initialize(bar = nil)
|
||||
# @bar = bar
|
||||
# end
|
||||
# delegate :zoo, :to => :bar
|
||||
# end
|
||||
#
|
||||
# Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
|
||||
#
|
||||
# class Foo
|
||||
# attr_accessor :bar
|
||||
# def initialize(bar = nil)
|
||||
# @bar = bar
|
||||
# end
|
||||
# delegate :zoo, :to => :bar, :allow_nil => true
|
||||
# end
|
||||
#
|
||||
# Foo.new.zoo # returns nil
|
||||
#
|
||||
def delegate(*methods)
|
||||
options = methods.pop
|
||||
unless options.is_a?(Hash) && to = options[:to]
|
||||
|
|
@ -84,11 +108,27 @@ class Module
|
|||
|
||||
prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_"
|
||||
|
||||
file, line = caller.first.split(':', 2)
|
||||
line = line.to_i
|
||||
|
||||
methods.each do |method|
|
||||
module_eval(<<-EOS, "(__DELEGATION__)", 1)
|
||||
def #{prefix}#{method}(*args, &block)
|
||||
#{to}.__send__(#{method.inspect}, *args, &block)
|
||||
on_nil =
|
||||
if options[:allow_nil]
|
||||
'return'
|
||||
else
|
||||
%(raise "#{prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
||||
end
|
||||
|
||||
module_eval(<<-EOS, file, line)
|
||||
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
||||
#{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
|
||||
rescue NoMethodError # rescue NoMethodError
|
||||
if #{to}.nil? # if client.nil?
|
||||
#{on_nil}
|
||||
else # else
|
||||
raise # raise
|
||||
end # end
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
module ActiveSupport
|
||||
class ModelName < String
|
||||
attr_reader :singular, :plural, :cache_key, :partial_path
|
||||
attr_reader :singular, :plural, :element, :collection, :partial_path
|
||||
alias_method :cache_key, :collection
|
||||
|
||||
def initialize(name)
|
||||
super
|
||||
@singular = underscore.tr('/', '_').freeze
|
||||
@plural = @singular.pluralize.freeze
|
||||
@cache_key = tableize.freeze
|
||||
@partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze
|
||||
@singular = ActiveSupport::Inflector.underscore(self).tr('/', '_').freeze
|
||||
@plural = ActiveSupport::Inflector.pluralize(@singular).freeze
|
||||
@element = ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self)).freeze
|
||||
@collection = ActiveSupport::Inflector.tableize(self).freeze
|
||||
@partial_path = "#{@collection}/#{@element}".freeze
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -16,7 +18,7 @@ module ActiveSupport
|
|||
# Returns an ActiveSupport::ModelName object for module. It can be
|
||||
# used to retrieve all kinds of naming-related information.
|
||||
def model_name
|
||||
@model_name ||= ModelName.new(name)
|
||||
@model_name ||= ::ActiveSupport::ModelName.new(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ class Module
|
|||
end
|
||||
|
||||
module_eval(<<-EOS, __FILE__, __LINE__)
|
||||
def #{aliased_method}_with_synchronization#{punctuation}(*args, &block)
|
||||
#{with}.synchronize do
|
||||
#{aliased_method}_without_synchronization#{punctuation}(*args, &block)
|
||||
end
|
||||
end
|
||||
def #{aliased_method}_with_synchronization#{punctuation}(*args, &block) # def expire_with_synchronization(*args, &block)
|
||||
#{with}.synchronize do # @@lock.synchronize do
|
||||
#{aliased_method}_without_synchronization#{punctuation}(*args, &block) # expire_without_synchronization(*args, &block)
|
||||
end # end
|
||||
end # end
|
||||
EOS
|
||||
|
||||
alias_method_chain method, :synchronization
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
class NameError #:nodoc:
|
||||
# Add a method to obtain the missing name from a NameError.
|
||||
def missing_name
|
||||
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
||||
if /undefined local variable or method/ !~ message
|
||||
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
||||
end
|
||||
end
|
||||
|
||||
# Was this exception raised because the given name was missing?
|
||||
|
|
|
|||
|
|
@ -3,41 +3,47 @@ module ActiveSupport #:nodoc:
|
|||
module Numeric #:nodoc:
|
||||
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
||||
module Bytes
|
||||
KILOBYTE = 1024
|
||||
MEGABYTE = KILOBYTE * 1024
|
||||
GIGABYTE = MEGABYTE * 1024
|
||||
TERABYTE = GIGABYTE * 1024
|
||||
PETABYTE = TERABYTE * 1024
|
||||
EXABYTE = PETABYTE * 1024
|
||||
|
||||
def bytes
|
||||
self
|
||||
end
|
||||
alias :byte :bytes
|
||||
|
||||
def kilobytes
|
||||
self * 1024
|
||||
self * KILOBYTE
|
||||
end
|
||||
alias :kilobyte :kilobytes
|
||||
|
||||
def megabytes
|
||||
self * 1024.kilobytes
|
||||
self * MEGABYTE
|
||||
end
|
||||
alias :megabyte :megabytes
|
||||
|
||||
def gigabytes
|
||||
self * 1024.megabytes
|
||||
self * GIGABYTE
|
||||
end
|
||||
alias :gigabyte :gigabytes
|
||||
|
||||
def terabytes
|
||||
self * 1024.gigabytes
|
||||
self * TERABYTE
|
||||
end
|
||||
alias :terabyte :terabytes
|
||||
|
||||
|
||||
def petabytes
|
||||
self * 1024.terabytes
|
||||
self * PETABYTE
|
||||
end
|
||||
alias :petabyte :petabytes
|
||||
|
||||
|
||||
def exabytes
|
||||
self * 1024.petabytes
|
||||
self * EXABYTE
|
||||
end
|
||||
alias :exabyte :exabytes
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/object/conversions'
|
||||
require 'active_support/core_ext/object/extending'
|
||||
require 'active_support/core_ext/object/instance_variables'
|
||||
|
|
|
|||
58
vendor/rails/activesupport/lib/active_support/core_ext/object/blank.rb
vendored
Normal file
58
vendor/rails/activesupport/lib/active_support/core_ext/object/blank.rb
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
class Object
|
||||
# An object is blank if it's false, empty, or a whitespace string.
|
||||
# For example, "", " ", +nil+, [], and {} are blank.
|
||||
#
|
||||
# This simplifies
|
||||
#
|
||||
# if !address.nil? && !address.empty?
|
||||
#
|
||||
# to
|
||||
#
|
||||
# if !address.blank?
|
||||
def blank?
|
||||
respond_to?(:empty?) ? empty? : !self
|
||||
end
|
||||
|
||||
# An object is present if it's not blank.
|
||||
def present?
|
||||
!blank?
|
||||
end
|
||||
end
|
||||
|
||||
class NilClass #:nodoc:
|
||||
def blank?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class FalseClass #:nodoc:
|
||||
def blank?
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class TrueClass #:nodoc:
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
class Array #:nodoc:
|
||||
alias_method :blank?, :empty?
|
||||
end
|
||||
|
||||
class Hash #:nodoc:
|
||||
alias_method :blank?, :empty?
|
||||
end
|
||||
|
||||
class String #:nodoc:
|
||||
def blank?
|
||||
self !~ /\S/
|
||||
end
|
||||
end
|
||||
|
||||
class Numeric #:nodoc:
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
@ -9,6 +9,7 @@ class Object
|
|||
#
|
||||
# Note: This method is defined as a default implementation for all Objects for Hash#to_query to work.
|
||||
def to_query(key)
|
||||
require 'cgi' unless defined?(CGI) && defined?(CGI::escape)
|
||||
"#{CGI.escape(key.to_s)}=#{CGI.escape(to_param.to_s)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,6 +40,21 @@ class Object
|
|||
value
|
||||
end
|
||||
|
||||
# Yields <code>x</code> to the block, and then returns <code>x</code>.
|
||||
# The primary purpose of this method is to "tap into" a method chain,
|
||||
# in order to perform operations on intermediate results within the chain.
|
||||
#
|
||||
# (1..10).tap { |x| puts "original: #{x.inspect}" }.to_a.
|
||||
# tap { |x| puts "array: #{x.inspect}" }.
|
||||
# select { |x| x%2 == 0 }.
|
||||
# tap { |x| puts "evens: #{x.inspect}" }.
|
||||
# map { |x| x*x }.
|
||||
# tap { |x| puts "squares: #{x.inspect}" }
|
||||
def tap
|
||||
yield self
|
||||
self
|
||||
end unless Object.respond_to?(:tap)
|
||||
|
||||
# An elegant way to factor duplication out of options passed to a series of
|
||||
# method calls. Each method called in the block, with the block variable as
|
||||
# the receiver, will have its options merged with the default +options+ hash
|
||||
|
|
@ -71,4 +86,5 @@ class Object
|
|||
def acts_like?(duck)
|
||||
respond_to? "acts_like_#{duck}?"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
# Gives a human readable format of the range.
|
||||
#
|
||||
# ==== Example:
|
||||
# ==== Example
|
||||
#
|
||||
# [1..100].to_formatted_s # => "1..100"
|
||||
def to_formatted_s(format = :default)
|
||||
|
|
|
|||
|
|
@ -1,34 +1,39 @@
|
|||
require 'rexml/document'
|
||||
require 'rexml/entity'
|
||||
|
||||
# Fixes the rexml vulnerability disclosed at:
|
||||
# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
|
||||
# This fix is identical to rexml-expansion-fix version 1.0.1
|
||||
require 'rexml/rexml'
|
||||
|
||||
# Earlier versions of rexml defined REXML::Version, newer ones REXML::VERSION
|
||||
unless REXML::Document.respond_to?(:entity_expansion_limit=)
|
||||
module REXML
|
||||
class Entity < Child
|
||||
undef_method :unnormalized
|
||||
def unnormalized
|
||||
document.record_entity_expansion! if document
|
||||
v = value()
|
||||
return nil if v.nil?
|
||||
@unnormalized = Text::unnormalize(v, parent)
|
||||
@unnormalized
|
||||
end
|
||||
end
|
||||
class Document < Element
|
||||
@@entity_expansion_limit = 10_000
|
||||
def self.entity_expansion_limit= val
|
||||
@@entity_expansion_limit = val
|
||||
end
|
||||
unless (defined?(REXML::VERSION) ? REXML::VERSION : REXML::Version) > "3.1.7.2"
|
||||
require 'rexml/document'
|
||||
|
||||
def record_entity_expansion!
|
||||
@number_of_expansions ||= 0
|
||||
@number_of_expansions += 1
|
||||
if @number_of_expansions > @@entity_expansion_limit
|
||||
raise "Number of entity expansions exceeded, processing aborted."
|
||||
# REXML in 1.8.7 has the patch but didn't update Version from 3.1.7.2.
|
||||
unless REXML::Document.respond_to?(:entity_expansion_limit=)
|
||||
require 'rexml/entity'
|
||||
|
||||
module REXML
|
||||
class Entity < Child
|
||||
undef_method :unnormalized
|
||||
def unnormalized
|
||||
document.record_entity_expansion! if document
|
||||
v = value()
|
||||
return nil if v.nil?
|
||||
@unnormalized = Text::unnormalize(v, parent)
|
||||
@unnormalized
|
||||
end
|
||||
end
|
||||
class Document < Element
|
||||
@@entity_expansion_limit = 10_000
|
||||
def self.entity_expansion_limit= val
|
||||
@@entity_expansion_limit = val
|
||||
end
|
||||
|
||||
def record_entity_expansion!
|
||||
@number_of_expansions ||= 0
|
||||
@number_of_expansions += 1
|
||||
if @number_of_expansions > @@entity_expansion_limit
|
||||
raise "Number of entity expansions exceeded, processing aborted."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
require 'active_support/core_ext/string/bytesize'
|
||||
require 'active_support/core_ext/string/conversions'
|
||||
require 'active_support/core_ext/string/access'
|
||||
require 'active_support/core_ext/string/starts_ends_with'
|
||||
|
|
@ -9,6 +10,7 @@ require 'active_support/core_ext/string/multibyte'
|
|||
require 'active_support/core_ext/string/xchar'
|
||||
require 'active_support/core_ext/string/filters'
|
||||
require 'active_support/core_ext/string/behavior'
|
||||
require 'active_support/core_ext/string/output_safety'
|
||||
|
||||
class String #:nodoc:
|
||||
include ActiveSupport::CoreExtensions::String::Access
|
||||
|
|
@ -19,4 +21,5 @@ class String #:nodoc:
|
|||
include ActiveSupport::CoreExtensions::String::Iterators
|
||||
include ActiveSupport::CoreExtensions::String::Behavior
|
||||
include ActiveSupport::CoreExtensions::String::Multibyte
|
||||
include ActiveSupport::CoreExtensions::String::OutputSafety
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41,9 +41,15 @@ module ActiveSupport #:nodoc:
|
|||
# "hello".first(2) # => "he"
|
||||
# "hello".first(10) # => "hello"
|
||||
def first(limit = 1)
|
||||
mb_chars[0..(limit - 1)].to_s
|
||||
if limit == 0
|
||||
''
|
||||
elsif limit >= size
|
||||
self
|
||||
else
|
||||
mb_chars[0...limit].to_s
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Returns the last character of the string or the last +limit+ characters.
|
||||
#
|
||||
# Examples:
|
||||
|
|
@ -51,7 +57,13 @@ module ActiveSupport #:nodoc:
|
|||
# "hello".last(2) # => "lo"
|
||||
# "hello".last(10) # => "hello"
|
||||
def last(limit = 1)
|
||||
(mb_chars[(-limit)..-1] || self).to_s
|
||||
if limit == 0
|
||||
''
|
||||
elsif limit >= size
|
||||
self
|
||||
else
|
||||
mb_chars[(-limit)..-1].to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
|
@ -69,11 +81,23 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
|
||||
def first(limit = 1)
|
||||
self[0..(limit - 1)]
|
||||
if limit == 0
|
||||
''
|
||||
elsif limit >= size
|
||||
self
|
||||
else
|
||||
to(limit - 1)
|
||||
end
|
||||
end
|
||||
|
||||
def last(limit = 1)
|
||||
from(-limit) || self
|
||||
if limit == 0
|
||||
''
|
||||
elsif limit >= size
|
||||
self
|
||||
else
|
||||
from(-limit)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
5
vendor/rails/activesupport/lib/active_support/core_ext/string/bytesize.rb
vendored
Normal file
5
vendor/rails/activesupport/lib/active_support/core_ext/string/bytesize.rb
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
unless '1.9'.respond_to?(:bytesize)
|
||||
class String
|
||||
alias :bytesize :size
|
||||
end
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
require 'active_support/inflector'
|
||||
require 'active_support/inflector' unless defined?(ActiveSupport::Inflector)
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
|
|
@ -102,8 +102,8 @@ module ActiveSupport #:nodoc:
|
|||
#
|
||||
# <%= link_to(@person.name, person_path %>
|
||||
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
||||
def parameterize
|
||||
Inflector.parameterize(self)
|
||||
def parameterize(sep = '-')
|
||||
Inflector.parameterize(self, sep)
|
||||
end
|
||||
|
||||
# Creates the name of a table like Rails does for models to table names. This method
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ module ActiveSupport #:nodoc:
|
|||
# When $KCODE = 'UTF8', multi-byte characters are yielded appropriately.
|
||||
def each_char
|
||||
scanner, char = StringScanner.new(self), /./mu
|
||||
loop { yield(scanner.scan(char) || break) }
|
||||
while c = scanner.scan(char)
|
||||
yield c
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
48
vendor/rails/activesupport/lib/active_support/core_ext/string/output_safety.rb
vendored
Normal file
48
vendor/rails/activesupport/lib/active_support/core_ext/string/output_safety.rb
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
module ActiveSupport #:nodoc:
|
||||
module CoreExtensions #:nodoc:
|
||||
module String #:nodoc:
|
||||
module OutputSafety
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
alias_method :add_without_safety, :+
|
||||
alias_method :+, :add_with_safety
|
||||
alias_method_chain :concat, :safety
|
||||
undef_method :<<
|
||||
alias_method :<<, :concat_with_safety
|
||||
end
|
||||
end
|
||||
|
||||
def html_safe?
|
||||
defined?(@_rails_html_safe) && @_rails_html_safe
|
||||
end
|
||||
|
||||
def html_safe!
|
||||
@_rails_html_safe = true
|
||||
self
|
||||
end
|
||||
|
||||
def add_with_safety(other)
|
||||
result = add_without_safety(other)
|
||||
if html_safe? && also_html_safe?(other)
|
||||
result.html_safe!
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
def concat_with_safety(other_or_fixnum)
|
||||
result = concat_without_safety(other_or_fixnum)
|
||||
unless html_safe? && also_html_safe?(other_or_fixnum)
|
||||
@_rails_html_safe = false
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
def also_html_safe?(other)
|
||||
other.respond_to?(:html_safe?) && other.html_safe?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -201,15 +201,16 @@ module ActiveSupport #:nodoc:
|
|||
|
||||
# Returns a new Time representing the start of the day (0:00)
|
||||
def beginning_of_day
|
||||
(self - self.seconds_since_midnight).change(:usec => 0)
|
||||
#(self - seconds_since_midnight).change(:usec => 0)
|
||||
change(:hour => 0, :min => 0, :sec => 0, :usec => 0)
|
||||
end
|
||||
alias :midnight :beginning_of_day
|
||||
alias :at_midnight :beginning_of_day
|
||||
alias :at_beginning_of_day :beginning_of_day
|
||||
|
||||
# Returns a new Time representing the end of the day (23:59:59)
|
||||
# Returns a new Time representing the end of the day, 23:59:59.999999 (.999999999 in ruby1.9)
|
||||
def end_of_day
|
||||
change(:hour => 23, :min => 59, :sec => 59)
|
||||
change(:hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
|
||||
end
|
||||
|
||||
# Returns a new Time representing the start of the month (1st of the month, 0:00)
|
||||
|
|
@ -219,11 +220,11 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
alias :at_beginning_of_month :beginning_of_month
|
||||
|
||||
# Returns a new Time representing the end of the month (last day of the month, 0:00)
|
||||
# Returns a new Time representing the end of the month (end of the last day of the month)
|
||||
def end_of_month
|
||||
#self - ((self.mday-1).days + self.seconds_since_midnight)
|
||||
last_day = ::Time.days_in_month( self.month, self.year )
|
||||
change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 0)
|
||||
change(:day => last_day, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
|
||||
end
|
||||
alias :at_end_of_month :end_of_month
|
||||
|
||||
|
|
@ -233,7 +234,7 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
alias :at_beginning_of_quarter :beginning_of_quarter
|
||||
|
||||
# Returns a new Time representing the end of the quarter (last day of march, june, september, december, 23:59:59)
|
||||
# Returns a new Time representing the end of the quarter (end of the last day of march, june, september, december)
|
||||
def end_of_quarter
|
||||
beginning_of_month.change(:month => [3, 6, 9, 12].detect { |m| m >= self.month }).end_of_month
|
||||
end
|
||||
|
|
@ -245,9 +246,9 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
alias :at_beginning_of_year :beginning_of_year
|
||||
|
||||
# Returns a new Time representing the end of the year (31st of december, 23:59:59)
|
||||
# Returns a new Time representing the end of the year (end of the 31st of december)
|
||||
def end_of_year
|
||||
change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59)
|
||||
change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59, :usec => 999999.999)
|
||||
end
|
||||
alias :at_end_of_year :end_of_year
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module ActiveSupport #:nodoc:
|
|||
:short => "%d %b %H:%M",
|
||||
:long => "%B %d, %Y %H:%M",
|
||||
:long_ordinal => lambda { |time| time.strftime("%B #{time.day.ordinalize}, %Y %H:%M") },
|
||||
:rfc822 => "%a, %d %b %Y %H:%M:%S %z"
|
||||
:rfc822 => lambda { |time| time.strftime("%a, %d %b %Y %H:%M:%S #{time.formatted_offset(false)}") }
|
||||
}
|
||||
|
||||
def self.included(base) #:nodoc:
|
||||
|
|
|
|||
36
vendor/rails/activesupport/lib/active_support/core_ext/try.rb
vendored
Normal file
36
vendor/rails/activesupport/lib/active_support/core_ext/try.rb
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
class Object
|
||||
# Invokes the method identified by the symbol +method+, passing it any arguments
|
||||
# and/or the block specified, just like the regular Ruby <tt>Object#send</tt> does.
|
||||
#
|
||||
# *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
|
||||
# and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# Without try
|
||||
# @person && @person.name
|
||||
# or
|
||||
# @person ? @person.name : nil
|
||||
#
|
||||
# With try
|
||||
# @person.try(:name)
|
||||
#
|
||||
# +try+ also accepts arguments and/or a block, for the method it is trying
|
||||
# Person.try(:find, 1)
|
||||
# @people.try(:collect) {|p| p.name}
|
||||
#--
|
||||
# This method definition below is for rdoc purposes only. The alias_method call
|
||||
# below overrides it as an optimization since +try+ behaves like +Object#send+,
|
||||
# unless called on +NilClass+.
|
||||
def try(method, *args, &block)
|
||||
send(method, *args, &block)
|
||||
end
|
||||
remove_method :try
|
||||
alias_method :try, :__send__
|
||||
end
|
||||
|
||||
class NilClass
|
||||
def try(*args)
|
||||
nil
|
||||
end
|
||||
end
|
||||
16
vendor/rails/activesupport/lib/active_support/core_ext/uri.rb
vendored
Normal file
16
vendor/rails/activesupport/lib/active_support/core_ext/uri.rb
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
if RUBY_VERSION >= '1.9'
|
||||
require 'uri'
|
||||
|
||||
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
|
||||
str.force_encoding(Encoding::UTF_8) if str.respond_to?(:force_encoding)
|
||||
|
||||
unless str == URI.unescape(URI.escape(str))
|
||||
URI::Parser.class_eval do
|
||||
remove_method :unescape
|
||||
def unescape(str, escaped = @regexp[:ESCAPED])
|
||||
enc = (str.encoding == Encoding::US_ASCII) ? Encoding::UTF_8 : str.encoding
|
||||
str.gsub(escaped) { [$&[1, 2].hex].pack('C') }.force_encoding(enc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -51,6 +51,9 @@ module ActiveSupport #:nodoc:
|
|||
mattr_accessor :constant_watch_stack
|
||||
self.constant_watch_stack = []
|
||||
|
||||
mattr_accessor :constant_watch_stack_mutex
|
||||
self.constant_watch_stack_mutex = Mutex.new
|
||||
|
||||
# Module includes this module
|
||||
module ModuleConstMissing #:nodoc:
|
||||
def self.included(base) #:nodoc:
|
||||
|
|
@ -319,12 +322,7 @@ module ActiveSupport #:nodoc:
|
|||
rescue NameError
|
||||
next
|
||||
end
|
||||
|
||||
[
|
||||
nesting.camelize,
|
||||
# Special case: application.rb might define ApplicationControlller.
|
||||
('ApplicationController' if nesting == 'application')
|
||||
]
|
||||
[ nesting_camel ]
|
||||
end.flatten.compact.uniq
|
||||
end
|
||||
|
||||
|
|
@ -514,7 +512,9 @@ module ActiveSupport #:nodoc:
|
|||
[mod_name, initial_constants]
|
||||
end
|
||||
|
||||
constant_watch_stack.concat watch_frames
|
||||
constant_watch_stack_mutex.synchronize do
|
||||
constant_watch_stack.concat watch_frames
|
||||
end
|
||||
|
||||
aborting = true
|
||||
begin
|
||||
|
|
@ -531,8 +531,10 @@ module ActiveSupport #:nodoc:
|
|||
new_constants = mod.local_constant_names - prior_constants
|
||||
|
||||
# Make sure no other frames takes credit for these constants.
|
||||
constant_watch_stack.each do |frame_name, constants|
|
||||
constants.concat new_constants if frame_name == mod_name
|
||||
constant_watch_stack_mutex.synchronize do
|
||||
constant_watch_stack.each do |frame_name, constants|
|
||||
constants.concat new_constants if frame_name == mod_name
|
||||
end
|
||||
end
|
||||
|
||||
new_constants.collect do |suffix|
|
||||
|
|
@ -554,8 +556,10 @@ module ActiveSupport #:nodoc:
|
|||
# Remove the stack frames that we added.
|
||||
if defined?(watch_frames) && ! watch_frames.blank?
|
||||
frame_ids = watch_frames.collect { |frame| frame.object_id }
|
||||
constant_watch_stack.delete_if do |watch_frame|
|
||||
frame_ids.include? watch_frame.object_id
|
||||
constant_watch_stack_mutex.synchronize do
|
||||
constant_watch_stack.delete_if do |watch_frame|
|
||||
frame_ids.include? watch_frame.object_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -564,9 +568,9 @@ module ActiveSupport #:nodoc:
|
|||
# Old style environment.rb referenced this method directly. Please note, it doesn't
|
||||
# actually *do* anything any more.
|
||||
def self.root(*args)
|
||||
if defined?(RAILS_DEFAULT_LOGGER)
|
||||
RAILS_DEFAULT_LOGGER.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
|
||||
RAILS_DEFAULT_LOGGER.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
|
||||
if defined?(Rails) && Rails.logger
|
||||
Rails.logger.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
|
||||
Rails.logger.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ module ActiveSupport
|
|||
$stderr.puts callstack.join("\n ") if debug
|
||||
},
|
||||
'development' => Proc.new { |message, callstack|
|
||||
logger = defined?(::RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stderr)
|
||||
logger = (defined?(Rails) && Rails.logger) ? Rails.logger : Logger.new($stderr)
|
||||
logger.warn message
|
||||
logger.debug callstack.join("\n ") if debug
|
||||
}
|
||||
|
|
@ -90,10 +90,15 @@ module ActiveSupport
|
|||
method_names.each do |method_name|
|
||||
alias_method_chain(method_name, :deprecation) do |target, punctuation|
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
def #{target}_with_deprecation#{punctuation}(*args, &block)
|
||||
::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(:#{method_name}, #{options[method_name].inspect}), caller)
|
||||
#{target}_without_deprecation#{punctuation}(*args, &block)
|
||||
end
|
||||
def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
|
||||
::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
|
||||
self.class.deprecated_method_warning( # self.class.deprecated_method_warning(
|
||||
:#{method_name}, # :generate_secret,
|
||||
#{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
|
||||
caller # caller
|
||||
) # )
|
||||
send(:#{target}_without_deprecation#{punctuation}, *args, &block) # send(:generate_secret_without_deprecation, *args, &block)
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
@ -113,37 +118,6 @@ module ActiveSupport
|
|||
end
|
||||
end
|
||||
|
||||
module Assertions #:nodoc:
|
||||
def assert_deprecated(match = nil, &block)
|
||||
result, warnings = collect_deprecations(&block)
|
||||
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
||||
if match
|
||||
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
|
||||
assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def assert_not_deprecated(&block)
|
||||
result, deprecations = collect_deprecations(&block)
|
||||
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
def collect_deprecations
|
||||
old_behavior = ActiveSupport::Deprecation.behavior
|
||||
deprecations = []
|
||||
ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
|
||||
deprecations << message
|
||||
end
|
||||
result = yield
|
||||
[result, deprecations]
|
||||
ensure
|
||||
ActiveSupport::Deprecation.behavior = old_behavior
|
||||
end
|
||||
end
|
||||
|
||||
class DeprecationProxy #:nodoc:
|
||||
silence_warnings do
|
||||
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
||||
|
|
@ -220,24 +194,3 @@ end
|
|||
class Module
|
||||
include ActiveSupport::Deprecation::ClassMethods
|
||||
end
|
||||
|
||||
require 'test/unit/error'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class TestCase
|
||||
include ActiveSupport::Deprecation::Assertions
|
||||
end
|
||||
|
||||
class Error # :nodoc:
|
||||
# Silence warnings when reporting test errors.
|
||||
def message_with_silenced_deprecation
|
||||
ActiveSupport::Deprecation.silence do
|
||||
message_without_silenced_deprecation
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :message, :silenced_deprecation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
require 'active_support/basic_object'
|
||||
|
||||
module ActiveSupport
|
||||
# Provides accurate date and time measurements using Date#advance and
|
||||
# Time#advance, respectively. It mainly supports the methods on Numeric,
|
||||
|
|
@ -65,10 +67,12 @@ module ActiveSupport
|
|||
|
||||
def inspect #:nodoc:
|
||||
consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h }
|
||||
[:years, :months, :days, :minutes, :seconds].map do |length|
|
||||
parts = [:years, :months, :days, :minutes, :seconds].map do |length|
|
||||
n = consolidated[length]
|
||||
"#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
|
||||
end.compact.to_sentence
|
||||
end.compact
|
||||
parts = ["0 seconds"] if parts.empty?
|
||||
parts.to_sentence(:locale => :en)
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ module ActiveSupport
|
|||
inflect.singular(/(vert|ind)ices$/i, '\1ex')
|
||||
inflect.singular(/(matr)ices$/i, '\1ix')
|
||||
inflect.singular(/(quiz)zes$/i, '\1')
|
||||
inflect.singular(/(database)s$/i, '\1')
|
||||
|
||||
inflect.irregular('person', 'people')
|
||||
inflect.irregular('man', 'men')
|
||||
|
|
|
|||
|
|
@ -254,18 +254,20 @@ module ActiveSupport
|
|||
# @person = Person.find(1)
|
||||
# # => #<Person id: 1, name: "Donald E. Knuth">
|
||||
#
|
||||
# <%= link_to(@person.name, person_path %>
|
||||
# <%= link_to(@person.name, person_path(@person)) %>
|
||||
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
||||
def parameterize(string, sep = '-')
|
||||
re_sep = Regexp.escape(sep)
|
||||
# replace accented chars with ther ascii equivalents
|
||||
parameterized_string = transliterate(string)
|
||||
# Turn unwanted chars into the seperator
|
||||
parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
|
||||
# No more than one of the separator in a row.
|
||||
parameterized_string.squeeze!(sep)
|
||||
# Remove leading/trailing separator.
|
||||
parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
|
||||
unless sep.blank?
|
||||
re_sep = Regexp.escape(sep)
|
||||
# No more than one of the separator in a row.
|
||||
parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
|
||||
# Remove leading/trailing separator.
|
||||
parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
|
||||
end
|
||||
parameterized_string.downcase
|
||||
end
|
||||
|
||||
|
|
@ -275,9 +277,16 @@ module ActiveSupport
|
|||
Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
|
||||
end
|
||||
|
||||
if RUBY_VERSION >= '1.9'
|
||||
undef_method :transliterate
|
||||
def transliterate(string)
|
||||
warn "Ruby 1.9 doesn't support Unicode normalization yet"
|
||||
string.dup
|
||||
end
|
||||
|
||||
# The iconv transliteration code doesn't function correctly
|
||||
# on some platforms, but it's very fast where it does function.
|
||||
if "foo" != Inflector.transliterate("föö")
|
||||
elsif "foo" != (Inflector.transliterate("föö") rescue nil)
|
||||
undef_method :transliterate
|
||||
def transliterate(string)
|
||||
string.mb_chars.normalize(:kd). # Decompose accented characters
|
||||
|
|
|
|||
|
|
@ -1,23 +1,2 @@
|
|||
module ActiveSupport
|
||||
# If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
|
||||
mattr_accessor :use_standard_json_time_format
|
||||
|
||||
class << self
|
||||
def escape_html_entities_in_json
|
||||
@escape_html_entities_in_json
|
||||
end
|
||||
|
||||
def escape_html_entities_in_json=(value)
|
||||
ActiveSupport::JSON::Encoding.escape_regex = \
|
||||
if value
|
||||
/[\010\f\n\r\t"\\><&]/
|
||||
else
|
||||
/[\010\f\n\r\t"\\]/
|
||||
end
|
||||
@escape_html_entities_in_json = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_support/json/encoding'
|
||||
require 'active_support/json/decoding'
|
||||
require 'active_support/json/encoding'
|
||||
|
|
|
|||
37
vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb
vendored
Normal file
37
vendor/rails/activesupport/lib/active_support/json/backends/jsongem.rb
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
require 'json' unless defined?(JSON)
|
||||
|
||||
module ActiveSupport
|
||||
module JSON
|
||||
module Backends
|
||||
module JSONGem
|
||||
ParseError = ::JSON::ParserError
|
||||
extend self
|
||||
|
||||
# Converts a JSON string into a Ruby object.
|
||||
def decode(json)
|
||||
data = ::JSON.parse(json)
|
||||
if ActiveSupport.parse_json_times
|
||||
convert_dates_from(data)
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def convert_dates_from(data)
|
||||
case data
|
||||
when DATE_REGEX
|
||||
DateTime.parse(data)
|
||||
when Array
|
||||
data.map! { |d| convert_dates_from(d) }
|
||||
when Hash
|
||||
data.each do |key, value|
|
||||
data[key] = convert_dates_from(value)
|
||||
end
|
||||
else data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
84
vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb
vendored
Normal file
84
vendor/rails/activesupport/lib/active_support/json/backends/yaml.rb
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
require 'active_support/core_ext/string/starts_ends_with'
|
||||
|
||||
module ActiveSupport
|
||||
module JSON
|
||||
module Backends
|
||||
module Yaml
|
||||
ParseError = ::StandardError
|
||||
extend self
|
||||
|
||||
# Converts a JSON string into a Ruby object.
|
||||
def decode(json)
|
||||
YAML.load(convert_json_to_yaml(json))
|
||||
rescue ArgumentError => e
|
||||
raise ParseError, "Invalid JSON string"
|
||||
end
|
||||
|
||||
protected
|
||||
# Ensure that ":" and "," are always followed by a space
|
||||
def convert_json_to_yaml(json) #:nodoc:
|
||||
require 'strscan' unless defined? ::StringScanner
|
||||
scanner, quoting, marks, pos, times = ::StringScanner.new(json), false, [], nil, []
|
||||
while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
|
||||
case char = scanner[1]
|
||||
when '"', "'"
|
||||
if !quoting
|
||||
quoting = char
|
||||
pos = scanner.pos
|
||||
elsif quoting == char
|
||||
if json[pos..scanner.pos-2] =~ DATE_REGEX
|
||||
# found a date, track the exact positions of the quotes so we can remove them later.
|
||||
# oh, and increment them for each current mark, each one is an extra padded space that bumps
|
||||
# the position in the final YAML output
|
||||
total_marks = marks.size
|
||||
times << pos+total_marks << scanner.pos+total_marks
|
||||
end
|
||||
quoting = false
|
||||
end
|
||||
when ":",","
|
||||
marks << scanner.pos - 1 unless quoting
|
||||
when "\\"
|
||||
scanner.skip(/\\/)
|
||||
end
|
||||
end
|
||||
|
||||
if marks.empty?
|
||||
json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
|
||||
ustr = $1
|
||||
if ustr.start_with?('u')
|
||||
[ustr[1..-1].to_i(16)].pack("U")
|
||||
elsif ustr == '\\'
|
||||
'\\\\'
|
||||
else
|
||||
ustr
|
||||
end
|
||||
end
|
||||
else
|
||||
left_pos = [-1].push(*marks)
|
||||
right_pos = marks << scanner.pos + scanner.rest_size
|
||||
output = []
|
||||
left_pos.each_with_index do |left, i|
|
||||
scanner.pos = left.succ
|
||||
output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
|
||||
ustr = $1
|
||||
if ustr.start_with?('u')
|
||||
[ustr[1..-1].to_i(16)].pack("U")
|
||||
elsif ustr == '\\'
|
||||
'\\\\'
|
||||
else
|
||||
ustr
|
||||
end
|
||||
end
|
||||
end
|
||||
output = output * " "
|
||||
|
||||
times.each { |i| output[i-1] = ' ' }
|
||||
output.gsub!(/\\\//, '/')
|
||||
output
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1,63 +1,35 @@
|
|||
require 'yaml'
|
||||
require 'strscan'
|
||||
require 'active_support/core_ext/module/attribute_accessors'
|
||||
|
||||
module ActiveSupport
|
||||
# Look for and parse json strings that look like ISO 8601 times.
|
||||
mattr_accessor :parse_json_times
|
||||
|
||||
module JSON
|
||||
class ParseError < StandardError
|
||||
end
|
||||
|
||||
class << self
|
||||
# Converts a JSON string into a Ruby object.
|
||||
def decode(json)
|
||||
YAML.load(convert_json_to_yaml(json))
|
||||
rescue ArgumentError => e
|
||||
raise ParseError, "Invalid JSON string"
|
||||
attr_reader :parse_error
|
||||
delegate :decode, :to => :backend
|
||||
|
||||
def backend
|
||||
self.backend = "Yaml" unless defined?(@backend)
|
||||
@backend
|
||||
end
|
||||
|
||||
protected
|
||||
# matches YAML-formatted dates
|
||||
DATE_REGEX = /^\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?$/
|
||||
|
||||
# Ensure that ":" and "," are always followed by a space
|
||||
def convert_json_to_yaml(json) #:nodoc:
|
||||
scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, []
|
||||
while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/)
|
||||
case char = scanner[1]
|
||||
when '"', "'"
|
||||
if !quoting
|
||||
quoting = char
|
||||
pos = scanner.pos
|
||||
elsif quoting == char
|
||||
if json[pos..scanner.pos-2] =~ DATE_REGEX
|
||||
# found a date, track the exact positions of the quotes so we can remove them later.
|
||||
# oh, and increment them for each current mark, each one is an extra padded space that bumps
|
||||
# the position in the final YAML output
|
||||
total_marks = marks.size
|
||||
times << pos+total_marks << scanner.pos+total_marks
|
||||
end
|
||||
quoting = false
|
||||
end
|
||||
when ":",","
|
||||
marks << scanner.pos - 1 unless quoting
|
||||
end
|
||||
end
|
||||
|
||||
if marks.empty?
|
||||
json.gsub(/\\\//, '/')
|
||||
else
|
||||
left_pos = [-1].push(*marks)
|
||||
right_pos = marks << json.length
|
||||
output = []
|
||||
left_pos.each_with_index do |left, i|
|
||||
output << json[left.succ..right_pos[i]]
|
||||
end
|
||||
output = output * " "
|
||||
|
||||
times.each { |i| output[i-1] = ' ' }
|
||||
output.gsub!(/\\\//, '/')
|
||||
output
|
||||
end
|
||||
def backend=(name)
|
||||
if name.is_a?(Module)
|
||||
@backend = name
|
||||
else
|
||||
require "active_support/json/backends/#{name.to_s.downcase}.rb"
|
||||
@backend = ActiveSupport::JSON::Backends::const_get(name)
|
||||
end
|
||||
@parse_error = @backend::ParseError
|
||||
end
|
||||
|
||||
def with_backend(name)
|
||||
old_backend, self.backend = backend, name
|
||||
yield
|
||||
ensure
|
||||
self.backend = old_backend
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
class Date
|
||||
# Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the
|
||||
# ISO 8601 format is used.
|
||||
# Coerces the date to a string for JSON encoding.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = true
|
||||
# ==== Examples
|
||||
#
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
||||
# Date.new(2005,2,1).to_json
|
||||
# # => "2005-02-01"
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = false
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
||||
# Date.new(2005,2,1).to_json
|
||||
# # => "2005/02/01"
|
||||
def to_json(options = nil)
|
||||
if ActiveSupport.use_standard_json_time_format
|
||||
%("#{strftime("%Y-%m-%d")}")
|
||||
def as_json(options = nil)
|
||||
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
||||
strftime("%Y-%m-%d")
|
||||
else
|
||||
%("#{strftime("%Y/%m/%d")}")
|
||||
strftime("%Y/%m/%d")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
class DateTime
|
||||
# Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the
|
||||
# ISO 8601 format is used.
|
||||
# Coerces the datetime to a string for JSON encoding.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = true
|
||||
# ==== Examples
|
||||
#
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
||||
# DateTime.civil(2005,2,1,15,15,10).to_json
|
||||
# # => "2005-02-01T15:15:10+00:00"
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = false
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
||||
# DateTime.civil(2005,2,1,15,15,10).to_json
|
||||
# # => "2005/02/01 15:15:10 +0000"
|
||||
def to_json(options = nil)
|
||||
if ActiveSupport.use_standard_json_time_format
|
||||
xmlschema.inspect
|
||||
def as_json(options = nil)
|
||||
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
||||
xmlschema
|
||||
else
|
||||
strftime('"%Y/%m/%d %H:%M:%S %z"')
|
||||
strftime('%Y/%m/%d %H:%M:%S %z')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
module Enumerable
|
||||
# Returns a JSON string representing the enumerable. Any +options+
|
||||
# given will be passed on to its elements. For example:
|
||||
#
|
||||
# users = User.find(:all)
|
||||
# # => users.to_json(:only => :name)
|
||||
#
|
||||
# will pass the <tt>:only => :name</tt> option to each user.
|
||||
def to_json(options = {}) #:nodoc:
|
||||
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ', '}]"
|
||||
# Coerces the enumerable to an array for JSON encoding.
|
||||
def as_json(options = nil) #:nodoc:
|
||||
to_a
|
||||
end
|
||||
end
|
||||
|
||||
class Array
|
||||
# Returns a JSON string representing the Array. +options+ are passed to each element.
|
||||
def to_json(options = nil) #:nodoc:
|
||||
"[#{map { |value| ActiveSupport::JSON.encode(value, options) } * ','}]"
|
||||
end
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class FalseClass
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'false'
|
||||
AS_JSON = ActiveSupport::JSON::Variable.new('false').freeze
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
AS_JSON
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
require 'active_support/core_ext/array/wrapper'
|
||||
|
||||
class Hash
|
||||
# Returns a JSON string representing the hash.
|
||||
#
|
||||
|
|
@ -5,7 +7,7 @@ class Hash
|
|||
# the hash keys. For example:
|
||||
#
|
||||
# { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
|
||||
# # => {"name": "Konata Izumi", 1: 2, "age": 16}
|
||||
# # => {"name": "Konata Izumi", "1": 2, "age": 16}
|
||||
#
|
||||
# The keys in the JSON string are unordered due to the nature of hashes.
|
||||
#
|
||||
|
|
@ -28,20 +30,27 @@ class Hash
|
|||
# would pass the <tt>:include => :posts</tt> option to <tt>users</tt>,
|
||||
# allowing the posts association in the User model to be converted to JSON
|
||||
# as well.
|
||||
def to_json(options = {}) #:nodoc:
|
||||
hash_keys = self.keys
|
||||
def to_json(options = nil) #:nodoc:
|
||||
hash = as_json(options)
|
||||
|
||||
if options[:except]
|
||||
hash_keys = hash_keys - Array(options[:except])
|
||||
elsif options[:only]
|
||||
hash_keys = hash_keys & Array(options[:only])
|
||||
end
|
||||
result = '{'
|
||||
result << hash.map do |key, value|
|
||||
"#{ActiveSupport::JSON.encode(key.to_s)}:#{ActiveSupport::JSON.encode(value, options)}"
|
||||
end * ','
|
||||
result << '}'
|
||||
end
|
||||
|
||||
returning result = '{' do
|
||||
result << hash_keys.map do |key|
|
||||
"#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(self[key], options)}"
|
||||
end * ', '
|
||||
result << '}'
|
||||
def as_json(options = nil) #:nodoc:
|
||||
if options
|
||||
if attrs = options[:except]
|
||||
except(*Array.wrap(attrs))
|
||||
elsif attrs = options[:only]
|
||||
slice(*Array.wrap(attrs))
|
||||
else
|
||||
self
|
||||
end
|
||||
else
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class NilClass
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'null'
|
||||
AS_JSON = ActiveSupport::JSON::Variable.new('null').freeze
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
AS_JSON
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,20 @@ class Numeric
|
|||
def to_json(options = nil) #:nodoc:
|
||||
to_s
|
||||
end
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
class Float
|
||||
def to_json(options = nil) #:nodoc:
|
||||
to_s
|
||||
end
|
||||
end
|
||||
|
||||
class Integer
|
||||
def to_json(options = nil) #:nodoc:
|
||||
to_s
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
class Object
|
||||
# Dumps object in JSON (JavaScript Object Notation). See www.json.org for more info.
|
||||
def to_json(options = {})
|
||||
ActiveSupport::JSON.encode(instance_values, options)
|
||||
def to_json(options = nil)
|
||||
ActiveSupport::JSON.encode(as_json(options))
|
||||
end
|
||||
|
||||
def as_json(options = nil)
|
||||
instance_values
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,4 +2,8 @@ class Regexp
|
|||
def to_json(options = nil) #:nodoc:
|
||||
inspect
|
||||
end
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,36 +1,9 @@
|
|||
module ActiveSupport
|
||||
module JSON
|
||||
module Encoding
|
||||
mattr_accessor :escape_regex
|
||||
|
||||
ESCAPED_CHARS = {
|
||||
"\010" => '\b',
|
||||
"\f" => '\f',
|
||||
"\n" => '\n',
|
||||
"\r" => '\r',
|
||||
"\t" => '\t',
|
||||
'"' => '\"',
|
||||
'\\' => '\\\\',
|
||||
'>' => '\u003E',
|
||||
'<' => '\u003C',
|
||||
'&' => '\u0026'
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveSupport.escape_html_entities_in_json = true
|
||||
|
||||
class String
|
||||
def to_json(options = nil) #:nodoc:
|
||||
json = '"' + gsub(ActiveSupport::JSON::Encoding.escape_regex) { |s|
|
||||
ActiveSupport::JSON::Encoding::ESCAPED_CHARS[s]
|
||||
}
|
||||
json.force_encoding('ascii-8bit') if respond_to?(:force_encoding)
|
||||
json.gsub(/([\xC0-\xDF][\x80-\xBF]|
|
||||
[\xE0-\xEF][\x80-\xBF]{2}|
|
||||
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
||||
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/, '\\\\u\&')
|
||||
} + '"'
|
||||
ActiveSupport::JSON::Encoding.escape(self)
|
||||
end
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
self
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
class Symbol
|
||||
def to_json(options = {}) #:nodoc:
|
||||
ActiveSupport::JSON.encode(to_s, options)
|
||||
def as_json(options = nil) #:nodoc:
|
||||
to_s
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
class Time
|
||||
# Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the
|
||||
# ISO 8601 format is used.
|
||||
# Coerces the time to a string for JSON encoding.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = true
|
||||
# ==== Examples
|
||||
#
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
||||
# Time.utc(2005,2,1,15,15,10).to_json
|
||||
# # => "2005-02-01T15:15:10Z"
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = false
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
||||
# Time.utc(2005,2,1,15,15,10).to_json
|
||||
# # => "2005/02/01 15:15:10 +0000"
|
||||
def to_json(options = nil)
|
||||
if ActiveSupport.use_standard_json_time_format
|
||||
xmlschema.inspect
|
||||
def as_json(options = nil)
|
||||
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
||||
xmlschema
|
||||
else
|
||||
%("#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
|
||||
%(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class TrueClass
|
||||
def to_json(options = nil) #:nodoc:
|
||||
'true'
|
||||
AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze
|
||||
|
||||
def as_json(options = nil) #:nodoc:
|
||||
AS_JSON
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,37 +1,102 @@
|
|||
require 'active_support/json/variable'
|
||||
require 'active_support/json/encoders/object' # Require explicitly for rdoc.
|
||||
Dir["#{File.dirname(__FILE__)}/encoders/**/*.rb"].each do |file|
|
||||
basename = File.basename(file, '.rb')
|
||||
unless basename == 'object'
|
||||
require "active_support/json/encoders/#{basename}"
|
||||
end
|
||||
end
|
||||
# encoding: utf-8
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/deprecation'
|
||||
|
||||
module ActiveSupport
|
||||
class << self
|
||||
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
|
||||
:escape_html_entities_in_json, :escape_html_entities_in_json=,
|
||||
:to => :'ActiveSupport::JSON::Encoding'
|
||||
end
|
||||
|
||||
module JSON
|
||||
class CircularReferenceError < StandardError
|
||||
end
|
||||
# matches YAML-formatted dates
|
||||
DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
|
||||
|
||||
class << self
|
||||
REFERENCE_STACK_VARIABLE = :json_reference_stack #:nodoc:
|
||||
delegate :encode, :to => :'ActiveSupport::JSON::Encoding'
|
||||
end
|
||||
|
||||
# Converts a Ruby object into a JSON string.
|
||||
def encode(value, options = {})
|
||||
raise_on_circular_reference(value) do
|
||||
value.send(:to_json, options)
|
||||
module Encoding #:nodoc:
|
||||
class CircularReferenceError < StandardError
|
||||
end
|
||||
|
||||
ESCAPED_CHARS = {
|
||||
"\010" => '\b',
|
||||
"\f" => '\f',
|
||||
"\n" => '\n',
|
||||
"\r" => '\r',
|
||||
"\t" => '\t',
|
||||
'"' => '\"',
|
||||
'\\' => '\\\\',
|
||||
'>' => '\u003E',
|
||||
'<' => '\u003C',
|
||||
'&' => '\u0026' }
|
||||
|
||||
class << self
|
||||
# If true, use ISO 8601 format for dates and times. Otherwise, fall back to the Active Support legacy format.
|
||||
attr_accessor :use_standard_json_time_format
|
||||
|
||||
attr_accessor :escape_regex
|
||||
attr_reader :escape_html_entities_in_json
|
||||
|
||||
def escape_html_entities_in_json=(value)
|
||||
self.escape_regex = \
|
||||
if @escape_html_entities_in_json = value
|
||||
/[\010\f\n\r\t"\\><&]/
|
||||
else
|
||||
/[\010\f\n\r\t"\\]/
|
||||
end
|
||||
end
|
||||
|
||||
def escape(string)
|
||||
string = string.dup.force_encoding(::Encoding::BINARY) if string.respond_to?(:force_encoding)
|
||||
json = string.
|
||||
gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
|
||||
gsub(/([\xC0-\xDF][\x80-\xBF]|
|
||||
[\xE0-\xEF][\x80-\xBF]{2}|
|
||||
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
|
||||
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
|
||||
}
|
||||
%("#{json}")
|
||||
end
|
||||
|
||||
# Converts a Ruby object into a JSON string.
|
||||
def encode(value, options = nil)
|
||||
options = {} unless Hash === options
|
||||
seen = (options[:seen] ||= [])
|
||||
raise CircularReferenceError, 'object references itself' if seen.include?(value)
|
||||
seen << value
|
||||
value.to_json(options)
|
||||
ensure
|
||||
seen.pop
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def raise_on_circular_reference(value) #:nodoc:
|
||||
stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
|
||||
raise CircularReferenceError, 'object references itself' if
|
||||
stack.include? value
|
||||
stack << value
|
||||
yield
|
||||
ensure
|
||||
stack.pop
|
||||
end
|
||||
self.escape_html_entities_in_json = true
|
||||
end
|
||||
|
||||
CircularReferenceError = Deprecation::DeprecatedConstantProxy.new('ActiveSupport::JSON::CircularReferenceError', Encoding::CircularReferenceError)
|
||||
end
|
||||
end
|
||||
|
||||
# Hack to load json gem first so we can overwrite its to_json.
|
||||
begin
|
||||
require 'json'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require 'active_support/json/variable'
|
||||
require 'active_support/json/encoders/date'
|
||||
require 'active_support/json/encoders/date_time'
|
||||
require 'active_support/json/encoders/enumerable'
|
||||
require 'active_support/json/encoders/false_class'
|
||||
require 'active_support/json/encoders/hash'
|
||||
require 'active_support/json/encoders/nil_class'
|
||||
require 'active_support/json/encoders/numeric'
|
||||
require 'active_support/json/encoders/object'
|
||||
require 'active_support/json/encoders/regexp'
|
||||
require 'active_support/json/encoders/string'
|
||||
require 'active_support/json/encoders/symbol'
|
||||
require 'active_support/json/encoders/time'
|
||||
require 'active_support/json/encoders/true_class'
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ en:
|
|||
# Used in array.to_sentence.
|
||||
support:
|
||||
array:
|
||||
sentence_connector: "and"
|
||||
skip_last_comma: false
|
||||
words_connector: ", "
|
||||
two_words_connector: " and "
|
||||
last_word_connector: ", and "
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
module ActiveSupport
|
||||
module Memoizable
|
||||
MEMOIZED_IVAR = Proc.new do |symbol|
|
||||
def self.memoized_ivar_for(symbol)
|
||||
"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym
|
||||
end
|
||||
|
||||
module Freezable
|
||||
module InstanceMethods
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
unless base.method_defined?(:freeze_without_memoizable)
|
||||
|
|
@ -19,23 +19,35 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
def memoize_all
|
||||
methods.each do |m|
|
||||
if m.to_s =~ /^_unmemoized_(.*)/
|
||||
if method(m).arity == 0
|
||||
__send__($1)
|
||||
else
|
||||
ivar = MEMOIZED_IVAR.call($1)
|
||||
instance_variable_set(ivar, {})
|
||||
prime_cache ".*"
|
||||
end
|
||||
|
||||
def unmemoize_all
|
||||
flush_cache ".*"
|
||||
end
|
||||
|
||||
def prime_cache(*syms)
|
||||
syms.each do |sym|
|
||||
methods.each do |m|
|
||||
if m.to_s =~ /^_unmemoized_(#{sym})/
|
||||
if method(m).arity == 0
|
||||
__send__($1)
|
||||
else
|
||||
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
|
||||
instance_variable_set(ivar, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def unmemoize_all
|
||||
methods.each do |m|
|
||||
if m.to_s =~ /^_unmemoized_(.*)/
|
||||
ivar = MEMOIZED_IVAR.call($1)
|
||||
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
|
||||
def flush_cache(*syms, &block)
|
||||
syms.each do |sym|
|
||||
(methods + private_methods + protected_methods).each do |m|
|
||||
if m.to_s =~ /^_unmemoized_(#{sym})/
|
||||
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
|
||||
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -44,37 +56,43 @@ module ActiveSupport
|
|||
def memoize(*symbols)
|
||||
symbols.each do |symbol|
|
||||
original_method = :"_unmemoized_#{symbol}"
|
||||
memoized_ivar = MEMOIZED_IVAR.call(symbol)
|
||||
memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol)
|
||||
|
||||
class_eval <<-EOS, __FILE__, __LINE__
|
||||
include Freezable
|
||||
|
||||
raise "Already memoized #{symbol}" if method_defined?(:#{original_method})
|
||||
alias #{original_method} #{symbol}
|
||||
|
||||
if instance_method(:#{symbol}).arity == 0
|
||||
def #{symbol}(reload = false)
|
||||
if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
|
||||
#{memoized_ivar} = [#{original_method}.freeze]
|
||||
end
|
||||
#{memoized_ivar}[0]
|
||||
end
|
||||
else
|
||||
def #{symbol}(*args)
|
||||
#{memoized_ivar} ||= {} unless frozen?
|
||||
reload = args.pop if args.last == true || args.last == :reload
|
||||
|
||||
if defined?(#{memoized_ivar}) && #{memoized_ivar}
|
||||
if !reload && #{memoized_ivar}.has_key?(args)
|
||||
#{memoized_ivar}[args]
|
||||
elsif #{memoized_ivar}
|
||||
#{memoized_ivar}[args] = #{original_method}(*args).freeze
|
||||
end
|
||||
else
|
||||
#{original_method}(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
include InstanceMethods # include InstanceMethods
|
||||
#
|
||||
if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type)
|
||||
raise "Already memoized #{symbol}" # raise "Already memoized mime_type"
|
||||
end # end
|
||||
alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type
|
||||
#
|
||||
if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
|
||||
def #{symbol}(reload = false) # def mime_type(reload = false)
|
||||
if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty?
|
||||
#{memoized_ivar} = [#{original_method}.freeze] # @_memoized_mime_type = [_unmemoized_mime_type.freeze]
|
||||
end # end
|
||||
#{memoized_ivar}[0] # @_memoized_mime_type[0]
|
||||
end # end
|
||||
else # else
|
||||
def #{symbol}(*args) # def mime_type(*args)
|
||||
#{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} unless frozen?
|
||||
reload = args.pop if args.last == true || args.last == :reload # reload = args.pop if args.last == true || args.last == :reload
|
||||
#
|
||||
if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_mime_type) && @_memoized_mime_type
|
||||
if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
|
||||
#{memoized_ivar}[args] # @_memoized_mime_type[args]
|
||||
elsif #{memoized_ivar} # elsif @_memoized_mime_type
|
||||
#{memoized_ivar}[args] = #{original_method}(*args).freeze # @_memoized_mime_type[args] = _unmemoized_mime_type(*args).freeze
|
||||
end # end
|
||||
else # else
|
||||
#{original_method}(*args) # _unmemoized_mime_type(*args)
|
||||
end # end
|
||||
end # end
|
||||
end # end
|
||||
#
|
||||
if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type)
|
||||
private #{symbol.inspect} # private :mime_type
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
end
|
||||
|
|
|
|||
70
vendor/rails/activesupport/lib/active_support/message_encryptor.rb
vendored
Normal file
70
vendor/rails/activesupport/lib/active_support/message_encryptor.rb
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
require 'openssl'
|
||||
|
||||
module ActiveSupport
|
||||
# MessageEncryptor is a simple way to encrypt values which get stored somewhere
|
||||
# you don't trust.
|
||||
#
|
||||
# The cipher text and initialization vector are base64 encoded and returned to you.
|
||||
#
|
||||
# This can be used in situations similar to the MessageVerifier, but where you don't
|
||||
# want users to be able to determine the value of the payload.
|
||||
class MessageEncryptor
|
||||
class InvalidMessage < StandardError; end
|
||||
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
|
||||
|
||||
def initialize(secret, cipher = 'aes-256-cbc')
|
||||
@secret = secret
|
||||
@cipher = cipher
|
||||
end
|
||||
|
||||
def encrypt(value)
|
||||
cipher = new_cipher
|
||||
# Rely on OpenSSL for the initialization vector
|
||||
iv = cipher.random_iv
|
||||
|
||||
cipher.encrypt
|
||||
cipher.key = @secret
|
||||
cipher.iv = iv
|
||||
|
||||
encrypted_data = cipher.update(Marshal.dump(value))
|
||||
encrypted_data << cipher.final
|
||||
|
||||
[encrypted_data, iv].map {|v| ActiveSupport::Base64.encode64s(v)}.join("--")
|
||||
end
|
||||
|
||||
def decrypt(encrypted_message)
|
||||
cipher = new_cipher
|
||||
encrypted_data, iv = encrypted_message.split("--").map {|v| ActiveSupport::Base64.decode64(v)}
|
||||
|
||||
cipher.decrypt
|
||||
cipher.key = @secret
|
||||
cipher.iv = iv
|
||||
|
||||
decrypted_data = cipher.update(encrypted_data)
|
||||
decrypted_data << cipher.final
|
||||
|
||||
Marshal.load(decrypted_data)
|
||||
rescue OpenSSLCipherError, TypeError
|
||||
raise InvalidMessage
|
||||
end
|
||||
|
||||
def encrypt_and_sign(value)
|
||||
verifier.generate(encrypt(value))
|
||||
end
|
||||
|
||||
def decrypt_and_verify(value)
|
||||
decrypt(verifier.verify(value))
|
||||
end
|
||||
|
||||
|
||||
|
||||
private
|
||||
def new_cipher
|
||||
OpenSSL::Cipher::Cipher.new(@cipher)
|
||||
end
|
||||
|
||||
def verifier
|
||||
MessageVerifier.new(@secret)
|
||||
end
|
||||
end
|
||||
end
|
||||
79
vendor/rails/activesupport/lib/active_support/message_verifier.rb
vendored
Normal file
79
vendor/rails/activesupport/lib/active_support/message_verifier.rb
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
module ActiveSupport
|
||||
# MessageVerifier makes it easy to generate and verify messages which are signed
|
||||
# to prevent tampering.
|
||||
#
|
||||
# This is useful for cases like remember-me tokens and auto-unsubscribe links where the
|
||||
# session store isn't suitable or available.
|
||||
#
|
||||
# Remember Me:
|
||||
# cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
|
||||
#
|
||||
# In the authentication filter:
|
||||
#
|
||||
# id, time = @verifier.verify(cookies[:remember_me])
|
||||
# if time < Time.now
|
||||
# self.current_user = User.find(id)
|
||||
# end
|
||||
#
|
||||
class MessageVerifier
|
||||
class InvalidSignature < StandardError; end
|
||||
|
||||
def initialize(secret, digest = 'SHA1')
|
||||
@secret = secret
|
||||
@digest = digest
|
||||
end
|
||||
|
||||
def verify(signed_message)
|
||||
raise InvalidSignature if signed_message.blank?
|
||||
|
||||
data, digest = signed_message.split("--")
|
||||
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
|
||||
Marshal.load(ActiveSupport::Base64.decode64(data))
|
||||
else
|
||||
raise InvalidSignature
|
||||
end
|
||||
end
|
||||
|
||||
def generate(value)
|
||||
data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
|
||||
"#{data}--#{generate_digest(data)}"
|
||||
end
|
||||
|
||||
private
|
||||
if "foo".respond_to?(:force_encoding)
|
||||
# constant-time comparison algorithm to prevent timing attacks
|
||||
def secure_compare(a, b)
|
||||
a = a.dup.force_encoding(Encoding::BINARY)
|
||||
b = b.dup.force_encoding(Encoding::BINARY)
|
||||
|
||||
if a.length == b.length
|
||||
result = 0
|
||||
for i in 0..(a.length - 1)
|
||||
result |= a[i].ord ^ b[i].ord
|
||||
end
|
||||
result == 0
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
else
|
||||
# For <= 1.8.6
|
||||
def secure_compare(a, b)
|
||||
if a.length == b.length
|
||||
result = 0
|
||||
for i in 0..(a.length - 1)
|
||||
result |= a[i] ^ b[i]
|
||||
end
|
||||
result == 0
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def generate_digest(data)
|
||||
require 'openssl' unless defined?(OpenSSL)
|
||||
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
# encoding: utf-8
|
||||
|
||||
require 'active_support/multibyte/chars'
|
||||
require 'active_support/multibyte/exceptions'
|
||||
require 'active_support/multibyte/unicode_database'
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module Multibyte
|
||||
# A list of all available normalization forms. See http://www.unicode.org/reports/tr15/tr15-29.html for more
|
||||
|
|
@ -27,7 +23,35 @@ module ActiveSupport #:nodoc:
|
|||
#
|
||||
# Example:
|
||||
# ActiveSupport::Multibyte.proxy_class = CharsForUTF32
|
||||
mattr_accessor :proxy_class
|
||||
self.proxy_class = ActiveSupport::Multibyte::Chars
|
||||
def self.proxy_class=(klass)
|
||||
@proxy_class = klass
|
||||
end
|
||||
|
||||
# Returns the currect proxy class
|
||||
def self.proxy_class
|
||||
@proxy_class ||= ActiveSupport::Multibyte::Chars
|
||||
end
|
||||
|
||||
# Regular expressions that describe valid byte sequences for a character
|
||||
VALID_CHARACTER = {
|
||||
# Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site)
|
||||
'UTF-8' => /\A(?:
|
||||
[\x00-\x7f] |
|
||||
[\xc2-\xdf] [\x80-\xbf] |
|
||||
\xe0 [\xa0-\xbf] [\x80-\xbf] |
|
||||
[\xe1-\xef] [\x80-\xbf] [\x80-\xbf] |
|
||||
\xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
||||
[\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
||||
\xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf])\z /xn,
|
||||
# Quick check for valid Shift-JIS characters, disregards the odd-even pairing
|
||||
'Shift_JIS' => /\A(?:
|
||||
[\x00-\x7e \xa1-\xdf] |
|
||||
[\x81-\x9f \xe0-\xef] [\x40-\x7e \x80-\x9e \x9f-\xfc])\z /xn
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
require 'active_support/multibyte/chars'
|
||||
require 'active_support/multibyte/exceptions'
|
||||
require 'active_support/multibyte/unicode_database'
|
||||
require 'active_support/multibyte/utils'
|
||||
|
|
|
|||
|
|
@ -73,16 +73,7 @@ module ActiveSupport #:nodoc:
|
|||
UNICODE_TRAILERS_PAT = /(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+\Z/
|
||||
UNICODE_LEADERS_PAT = /\A(#{codepoints_to_pattern(UNICODE_LEADERS_AND_TRAILERS)})+/
|
||||
|
||||
# Borrowed from the Kconv library by Shinji KONO - (also as seen on the W3C site)
|
||||
UTF8_PAT = /\A(?:
|
||||
[\x00-\x7f] |
|
||||
[\xc2-\xdf] [\x80-\xbf] |
|
||||
\xe0 [\xa0-\xbf] [\x80-\xbf] |
|
||||
[\xe1-\xef] [\x80-\xbf] [\x80-\xbf] |
|
||||
\xf0 [\x90-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
||||
[\xf1-\xf3] [\x80-\xbf] [\x80-\xbf] [\x80-\xbf] |
|
||||
\xf4 [\x80-\x8f] [\x80-\xbf] [\x80-\xbf]
|
||||
)*\z/xn
|
||||
UTF8_PAT = ActiveSupport::Multibyte::VALID_CHARACTER['UTF-8']
|
||||
|
||||
attr_reader :wrapped_string
|
||||
alias to_s wrapped_string
|
||||
|
|
@ -205,7 +196,22 @@ module ActiveSupport #:nodoc:
|
|||
# 'Café périferôl'.mb_chars.index('ô') #=> 12
|
||||
# 'Café périferôl'.mb_chars.index(/\w/u) #=> 0
|
||||
def index(needle, offset=0)
|
||||
index = @wrapped_string.index(needle, offset)
|
||||
wrapped_offset = self.first(offset).wrapped_string.length
|
||||
index = @wrapped_string.index(needle, wrapped_offset)
|
||||
index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
|
||||
end
|
||||
|
||||
# Returns the position _needle_ in the string, counting in
|
||||
# codepoints, searching backward from _offset_ or the end of the
|
||||
# string. Returns +nil+ if _needle_ isn't found.
|
||||
#
|
||||
# Example:
|
||||
# 'Café périferôl'.mb_chars.rindex('é') #=> 6
|
||||
# 'Café périferôl'.mb_chars.rindex(/\w/u) #=> 13
|
||||
def rindex(needle, offset=nil)
|
||||
offset ||= length
|
||||
wrapped_offset = self.first(offset).wrapped_string.length
|
||||
index = @wrapped_string.rindex(needle, wrapped_offset)
|
||||
index ? (self.class.u_unpack(@wrapped_string.slice(0...index)).size) : nil
|
||||
end
|
||||
|
||||
|
|
@ -292,31 +298,31 @@ module ActiveSupport #:nodoc:
|
|||
def rstrip
|
||||
chars(@wrapped_string.gsub(UNICODE_TRAILERS_PAT, ''))
|
||||
end
|
||||
|
||||
|
||||
# Strips entire range of Unicode whitespace from the left of the string.
|
||||
def lstrip
|
||||
chars(@wrapped_string.gsub(UNICODE_LEADERS_PAT, ''))
|
||||
end
|
||||
|
||||
|
||||
# Strips entire range of Unicode whitespace from the right and left of the string.
|
||||
def strip
|
||||
rstrip.lstrip
|
||||
end
|
||||
|
||||
|
||||
# Returns the number of codepoints in the string
|
||||
def size
|
||||
self.class.u_unpack(@wrapped_string).size
|
||||
end
|
||||
alias_method :length, :size
|
||||
|
||||
|
||||
# Reverses all characters in the string.
|
||||
#
|
||||
# Example:
|
||||
# 'Café'.mb_chars.reverse.to_s #=> 'éfaC'
|
||||
def reverse
|
||||
chars(self.class.u_unpack(@wrapped_string).reverse.pack('U*'))
|
||||
chars(self.class.g_unpack(@wrapped_string).reverse.flatten.pack('U*'))
|
||||
end
|
||||
|
||||
|
||||
# Implements Unicode-aware slice with codepoints. Slicing on one point returns the codepoints for that
|
||||
# character.
|
||||
#
|
||||
|
|
@ -344,6 +350,26 @@ module ActiveSupport #:nodoc:
|
|||
end
|
||||
alias_method :[], :slice
|
||||
|
||||
# Like <tt>String#slice!</tt>, except instead of byte offsets you specify character offsets.
|
||||
#
|
||||
# Example:
|
||||
# s = 'こんにちは'
|
||||
# s.mb_chars.slice!(2..3).to_s #=> "にち"
|
||||
# s #=> "こんは"
|
||||
def slice!(*args)
|
||||
slice = self[*args]
|
||||
self[*args] = ''
|
||||
slice
|
||||
end
|
||||
|
||||
# Returns the codepoint of the first character in the string.
|
||||
#
|
||||
# Example:
|
||||
# 'こんにちは'.mb_chars.ord #=> 12371
|
||||
def ord
|
||||
self.class.u_unpack(@wrapped_string)[0]
|
||||
end
|
||||
|
||||
# Convert characters in the string to uppercase.
|
||||
#
|
||||
# Example:
|
||||
|
|
@ -424,7 +450,7 @@ module ActiveSupport #:nodoc:
|
|||
chars(self.class.tidy_bytes(@wrapped_string))
|
||||
end
|
||||
|
||||
%w(lstrip rstrip strip reverse upcase downcase slice tidy_bytes capitalize).each do |method|
|
||||
%w(lstrip rstrip strip reverse upcase downcase tidy_bytes capitalize).each do |method|
|
||||
define_method("#{method}!") do |*args|
|
||||
unless args.nil?
|
||||
@wrapped_string = send(method, *args).to_s
|
||||
|
|
@ -609,7 +635,9 @@ module ActiveSupport #:nodoc:
|
|||
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent resulting in a valid UTF-8 string.
|
||||
def tidy_bytes(string)
|
||||
string.split(//u).map do |c|
|
||||
if !UTF8_PAT.match(c)
|
||||
c.force_encoding(Encoding::ASCII) if c.respond_to?(:force_encoding)
|
||||
|
||||
if !ActiveSupport::Multibyte::VALID_CHARACTER['UTF-8'].match(c)
|
||||
n = c.unpack('C')[0]
|
||||
n < 128 ? n.chr :
|
||||
n < 160 ? [UCD.cp1252[n] || n].pack('U') :
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ module ActiveSupport #:nodoc:
|
|||
# Lazy load the Unicode database so it's only loaded when it's actually used
|
||||
ATTRIBUTES.each do |attr_name|
|
||||
class_eval(<<-EOS, __FILE__, __LINE__)
|
||||
def #{attr_name}
|
||||
load
|
||||
@#{attr_name}
|
||||
end
|
||||
def #{attr_name} # def codepoints
|
||||
load # load
|
||||
@#{attr_name} # @codepoints
|
||||
end # end
|
||||
EOS
|
||||
end
|
||||
|
||||
|
|
|
|||
61
vendor/rails/activesupport/lib/active_support/multibyte/utils.rb
vendored
Normal file
61
vendor/rails/activesupport/lib/active_support/multibyte/utils.rb
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# encoding: utf-8
|
||||
|
||||
module ActiveSupport #:nodoc:
|
||||
module Multibyte #:nodoc:
|
||||
if Kernel.const_defined?(:Encoding)
|
||||
# Returns a regular expression that matches valid characters in the current encoding
|
||||
def self.valid_character
|
||||
VALID_CHARACTER[Encoding.default_external.to_s]
|
||||
end
|
||||
else
|
||||
def self.valid_character
|
||||
case $KCODE
|
||||
when 'UTF8'
|
||||
VALID_CHARACTER['UTF-8']
|
||||
when 'SJIS'
|
||||
VALID_CHARACTER['Shift_JIS']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if 'string'.respond_to?(:valid_encoding?)
|
||||
# Verifies the encoding of a string
|
||||
def self.verify(string)
|
||||
string.valid_encoding?
|
||||
end
|
||||
else
|
||||
def self.verify(string)
|
||||
if expression = valid_character
|
||||
for c in string.split(//)
|
||||
return false unless expression.match(c)
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
# Verifies the encoding of the string and raises an exception when it's not valid
|
||||
def self.verify!(string)
|
||||
raise EncodingError.new("Found characters with invalid encoding") unless verify(string)
|
||||
end
|
||||
|
||||
if 'string'.respond_to?(:force_encoding)
|
||||
# Removes all invalid characters from the string.
|
||||
#
|
||||
# Note: this method is a no-op in Ruby 1.9
|
||||
def self.clean(string)
|
||||
string
|
||||
end
|
||||
else
|
||||
def self.clean(string)
|
||||
if expression = valid_character
|
||||
stripped = []; for c in string.split(//)
|
||||
stripped << c if expression.match(c)
|
||||
end; stripped.join
|
||||
else
|
||||
string
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,13 @@ module ActiveSupport
|
|||
|
||||
private
|
||||
def method_missing(method, *arguments, &block)
|
||||
arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
|
||||
if arguments.last.is_a?(Proc)
|
||||
proc = arguments.pop
|
||||
arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) }
|
||||
else
|
||||
arguments << (arguments.last.respond_to?(:to_hash) ? @options.deep_merge(arguments.pop) : @options.dup)
|
||||
end
|
||||
|
||||
@context.__send__(method, *arguments, &block)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,55 +4,138 @@ module ActiveSupport
|
|||
if RUBY_VERSION >= '1.9'
|
||||
OrderedHash = ::Hash
|
||||
else
|
||||
class OrderedHash < Array #:nodoc:
|
||||
def []=(key, value)
|
||||
if pair = assoc(key)
|
||||
pair.pop
|
||||
pair << value
|
||||
else
|
||||
self << [key, value]
|
||||
end
|
||||
value
|
||||
class OrderedHash < Hash #:nodoc:
|
||||
def initialize(*args, &block)
|
||||
super
|
||||
@keys = []
|
||||
end
|
||||
|
||||
def [](key)
|
||||
pair = assoc(key)
|
||||
pair ? pair.last : nil
|
||||
def self.[](*args)
|
||||
ordered_hash = new
|
||||
|
||||
if (args.length == 1 && args.first.is_a?(Array))
|
||||
args.first.each do |key_value_pair|
|
||||
next unless (key_value_pair.is_a?(Array))
|
||||
ordered_hash[key_value_pair[0]] = key_value_pair[1]
|
||||
end
|
||||
|
||||
return ordered_hash
|
||||
end
|
||||
|
||||
unless (args.size % 2 == 0)
|
||||
raise ArgumentError.new("odd number of arguments for Hash")
|
||||
end
|
||||
|
||||
args.each_with_index do |val, ind|
|
||||
next if (ind % 2 != 0)
|
||||
ordered_hash[val] = args[ind + 1]
|
||||
end
|
||||
|
||||
ordered_hash
|
||||
end
|
||||
|
||||
def initialize_copy(other)
|
||||
super
|
||||
# make a deep copy of keys
|
||||
@keys = other.keys
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
@keys << key if !has_key?(key)
|
||||
super
|
||||
end
|
||||
|
||||
def delete(key)
|
||||
pair = assoc(key)
|
||||
pair ? array_index = index(pair) : nil
|
||||
array_index ? delete_at(array_index).last : nil
|
||||
if has_key? key
|
||||
index = @keys.index(key)
|
||||
@keys.delete_at index
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def delete_if
|
||||
super
|
||||
sync_keys!
|
||||
self
|
||||
end
|
||||
|
||||
def reject!
|
||||
super
|
||||
sync_keys!
|
||||
self
|
||||
end
|
||||
|
||||
def reject(&block)
|
||||
dup.reject!(&block)
|
||||
end
|
||||
|
||||
def keys
|
||||
collect { |key, value| key }
|
||||
@keys.dup
|
||||
end
|
||||
|
||||
def values
|
||||
collect { |key, value| value }
|
||||
@keys.collect { |key| self[key] }
|
||||
end
|
||||
|
||||
def to_hash
|
||||
returning({}) do |hash|
|
||||
each { |array| hash[array[0]] = array[1] }
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def has_key?(k)
|
||||
!assoc(k).nil?
|
||||
def to_a
|
||||
@keys.map { |key| [ key, self[key] ] }
|
||||
end
|
||||
|
||||
alias_method :key?, :has_key?
|
||||
alias_method :include?, :has_key?
|
||||
alias_method :member?, :has_key?
|
||||
|
||||
def has_value?(v)
|
||||
any? { |key, value| value == v }
|
||||
def each_key
|
||||
@keys.each { |key| yield key }
|
||||
end
|
||||
|
||||
alias_method :value?, :has_value?
|
||||
def each_value
|
||||
@keys.each { |key| yield self[key]}
|
||||
end
|
||||
|
||||
def each
|
||||
@keys.each {|key| yield [key, self[key]]}
|
||||
end
|
||||
|
||||
alias_method :each_pair, :each
|
||||
|
||||
def clear
|
||||
super
|
||||
@keys.clear
|
||||
self
|
||||
end
|
||||
|
||||
def shift
|
||||
k = @keys.first
|
||||
v = delete(k)
|
||||
[k, v]
|
||||
end
|
||||
|
||||
def merge!(other_hash)
|
||||
other_hash.each {|k,v| self[k] = v }
|
||||
self
|
||||
end
|
||||
|
||||
def merge(other_hash)
|
||||
dup.merge!(other_hash)
|
||||
end
|
||||
|
||||
# When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
|
||||
def replace(other)
|
||||
super
|
||||
@keys = other.keys
|
||||
self
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<OrderedHash #{super}>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sync_keys!
|
||||
@keys.delete_if {|k| !has_key?(k)}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
begin
|
||||
require 'openssl'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
begin
|
||||
require 'securerandom'
|
||||
rescue LoadError
|
||||
|
|
@ -10,7 +5,7 @@ end
|
|||
|
||||
module ActiveSupport
|
||||
if defined?(::SecureRandom)
|
||||
# Use Ruby 1.9's SecureRandom library whenever possible.
|
||||
# Use Ruby's SecureRandom library if available.
|
||||
SecureRandom = ::SecureRandom # :nodoc:
|
||||
else
|
||||
# = Secure random number generator interface.
|
||||
|
|
@ -64,6 +59,13 @@ module ActiveSupport
|
|||
def self.random_bytes(n=nil)
|
||||
n ||= 16
|
||||
|
||||
unless defined? OpenSSL
|
||||
begin
|
||||
require 'openssl'
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
if defined? OpenSSL::Random
|
||||
return OpenSSL::Random.random_bytes(n)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,24 +1,40 @@
|
|||
require 'test/unit/testcase'
|
||||
require 'active_support/testing/default'
|
||||
require 'active_support/testing/core_ext/test'
|
||||
require 'active_support/testing/setup_and_teardown'
|
||||
require 'active_support/testing/assertions'
|
||||
require 'active_support/testing/deprecation'
|
||||
require 'active_support/testing/declarative'
|
||||
|
||||
begin
|
||||
gem 'mocha', ">= 0.9.7"
|
||||
require 'mocha'
|
||||
rescue LoadError
|
||||
# Fake Mocha::ExpectationError so we can rescue it in #run. Bleh.
|
||||
Object.const_set :Mocha, Module.new
|
||||
Mocha.const_set :ExpectationError, Class.new(StandardError)
|
||||
end
|
||||
|
||||
module ActiveSupport
|
||||
class TestCase < Test::Unit::TestCase
|
||||
# test "verify something" do
|
||||
# ...
|
||||
# end
|
||||
def self.test(name, &block)
|
||||
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
||||
defined = instance_method(test_name) rescue false
|
||||
raise "#{test_name} is already defined in #{self}" if defined
|
||||
if block_given?
|
||||
define_method(test_name, &block)
|
||||
else
|
||||
define_method(test_name) do
|
||||
flunk "No implementation provided for #{name}"
|
||||
end
|
||||
class TestCase < ::Test::Unit::TestCase
|
||||
if defined? MiniTest
|
||||
Assertion = MiniTest::Assertion
|
||||
alias_method :method_name, :name if method_defined? :name
|
||||
alias_method :method_name, :__name__ if method_defined? :__name__
|
||||
else
|
||||
# TODO: Figure out how to get the Rails::BacktraceFilter into minitest/unit
|
||||
if defined?(Rails) && ENV['BACKTRACE'].nil?
|
||||
require 'rails/backtrace_cleaner'
|
||||
Test::Unit::Util::BacktraceFilter.module_eval { include Rails::BacktraceFilterForTestUnit }
|
||||
end
|
||||
|
||||
Assertion = Test::Unit::AssertionFailedError
|
||||
|
||||
require 'active_support/testing/default'
|
||||
include ActiveSupport::Testing::Default
|
||||
end
|
||||
|
||||
include ActiveSupport::Testing::SetupAndTeardown
|
||||
include ActiveSupport::Testing::Assertions
|
||||
include ActiveSupport::Testing::Deprecation
|
||||
extend ActiveSupport::Testing::Declarative
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
require 'test/unit/assertions'
|
||||
module Test
|
||||
module Unit
|
||||
#--
|
||||
# FIXME: no Proc#binding in Ruby 2, must change this API
|
||||
#++
|
||||
module ActiveSupport
|
||||
module Testing
|
||||
module Assertions
|
||||
# Test numeric difference between the return value of an expression as a result of what is evaluated
|
||||
# in the yielded block.
|
||||
|
|
@ -35,20 +31,17 @@ module Test
|
|||
# assert_difference 'Article.count', -1, "An Article should be destroyed" do
|
||||
# post :delete, :id => ...
|
||||
# end
|
||||
def assert_difference(expressions, difference = 1, message = nil, &block)
|
||||
expression_evaluations = Array(expressions).map do |expression|
|
||||
[expression, lambda do
|
||||
eval(expression, block.__send__(:binding))
|
||||
end]
|
||||
end
|
||||
def assert_difference(expression, difference = 1, message = nil, &block)
|
||||
b = block.send(:binding)
|
||||
exps = Array.wrap(expression)
|
||||
before = exps.map { |e| eval(e, b) }
|
||||
|
||||
original_values = expression_evaluations.inject([]) { |memo, expression| memo << expression[1].call }
|
||||
yield
|
||||
expression_evaluations.each_with_index do |expression, i|
|
||||
full_message = ""
|
||||
full_message << "#{message}.\n" if message
|
||||
full_message << "<#{expression[0]}> was the expression that failed"
|
||||
assert_equal original_values[i] + difference, expression[1].call, full_message
|
||||
|
||||
exps.each_with_index do |e, i|
|
||||
error = "#{e.inspect} didn't change by #{difference}"
|
||||
error = "#{message}.\n#{error}" if message
|
||||
assert_equal(before[i] + difference, eval(e, b), error)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -64,8 +57,8 @@ module Test
|
|||
# assert_no_difference 'Article.count', "An Article should not be destroyed" do
|
||||
# post :create, :article => invalid_attributes
|
||||
# end
|
||||
def assert_no_difference(expressions, message = nil, &block)
|
||||
assert_difference expressions, 0, message, &block
|
||||
def assert_no_difference(expression, message = nil, &block)
|
||||
assert_difference expression, 0, message, &block
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
require 'active_support/testing/core_ext/test/unit/assertions'
|
||||
require 'active_support/testing/setup_and_teardown'
|
||||
|
||||
class Test::Unit::TestCase #:nodoc:
|
||||
include ActiveSupport::Testing::SetupAndTeardown
|
||||
end
|
||||
21
vendor/rails/activesupport/lib/active_support/testing/declarative.rb
vendored
Normal file
21
vendor/rails/activesupport/lib/active_support/testing/declarative.rb
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
module ActiveSupport
|
||||
module Testing
|
||||
module Declarative
|
||||
# test "verify something" do
|
||||
# ...
|
||||
# end
|
||||
def test(name, &block)
|
||||
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
||||
defined = instance_method(test_name) rescue false
|
||||
raise "#{test_name} is already defined in #{self}" if defined
|
||||
if block_given?
|
||||
define_method(test_name, &block)
|
||||
else
|
||||
define_method(test_name) do
|
||||
flunk "No implementation provided for #{name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
57
vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
vendored
Normal file
57
vendor/rails/activesupport/lib/active_support/testing/deprecation.rb
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
require "active_support/core_ext/module"
|
||||
|
||||
module ActiveSupport
|
||||
module Testing
|
||||
module Deprecation #:nodoc:
|
||||
def assert_deprecated(match = nil, &block)
|
||||
result, warnings = collect_deprecations(&block)
|
||||
assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
|
||||
if match
|
||||
match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
|
||||
assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def assert_not_deprecated(&block)
|
||||
result, deprecations = collect_deprecations(&block)
|
||||
assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
|
||||
result
|
||||
end
|
||||
|
||||
private
|
||||
def collect_deprecations
|
||||
old_behavior = ActiveSupport::Deprecation.behavior
|
||||
deprecations = []
|
||||
ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
|
||||
deprecations << message
|
||||
end
|
||||
result = yield
|
||||
[result, deprecations]
|
||||
ensure
|
||||
ActiveSupport::Deprecation.behavior = old_behavior
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
require 'test/unit/error'
|
||||
|
||||
module Test
|
||||
module Unit
|
||||
class Error # :nodoc:
|
||||
# Silence warnings when reporting test errors.
|
||||
def message_with_silenced_deprecation
|
||||
ActiveSupport::Deprecation.silence do
|
||||
message_without_silenced_deprecation
|
||||
end
|
||||
end
|
||||
|
||||
alias_method_chain :message, :silenced_deprecation
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
# Using miniunit, ignore.
|
||||
end
|
||||
|
|
@ -12,7 +12,7 @@ module ActiveSupport
|
|||
if benchmark = ARGV.include?('--benchmark') # HAX for rake test
|
||||
{ :benchmark => true,
|
||||
:runs => 4,
|
||||
:metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time],
|
||||
:metrics => [:wall_time, :memory, :objects, :gc_runs, :gc_time],
|
||||
:output => 'tmp/performance' }
|
||||
else
|
||||
{ :benchmark => false,
|
||||
|
|
|
|||
|
|
@ -1,119 +1,90 @@
|
|||
require 'active_support/callbacks'
|
||||
|
||||
module ActiveSupport
|
||||
module Testing
|
||||
module SetupAndTeardown
|
||||
# For compatibility with Ruby < 1.8.6
|
||||
PASSTHROUGH_EXCEPTIONS =
|
||||
if defined?(Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS)
|
||||
Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
|
||||
else
|
||||
[NoMemoryError, SignalException, Interrupt, SystemExit]
|
||||
end
|
||||
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
include ActiveSupport::Callbacks
|
||||
define_callbacks :setup, :teardown
|
||||
|
||||
if defined?(::Mini)
|
||||
undef_method :run
|
||||
alias_method :run, :run_with_callbacks_and_miniunit
|
||||
if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions
|
||||
include ForMiniTest
|
||||
else
|
||||
begin
|
||||
require 'mocha'
|
||||
undef_method :run
|
||||
alias_method :run, :run_with_callbacks_and_mocha
|
||||
rescue LoadError
|
||||
undef_method :run
|
||||
alias_method :run, :run_with_callbacks_and_testunit
|
||||
end
|
||||
include ForClassicTestUnit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def run_with_callbacks_and_miniunit(runner)
|
||||
result = '.'
|
||||
begin
|
||||
run_callbacks :setup
|
||||
result = super
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# This redefinition is unfortunate but test/unit shows us no alternative.
|
||||
def run_with_callbacks_and_testunit(result) #:nodoc:
|
||||
return if @method_name.to_s == "default_test"
|
||||
|
||||
yield(Test::Unit::TestCase::STARTED, name)
|
||||
@_result = result
|
||||
begin
|
||||
run_callbacks :setup
|
||||
setup
|
||||
__send__(@method_name)
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue *PASSTHROUGH_EXCEPTIONS
|
||||
raise
|
||||
rescue Exception
|
||||
add_error($!)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue *PASSTHROUGH_EXCEPTIONS
|
||||
raise
|
||||
rescue Exception
|
||||
add_error($!)
|
||||
end
|
||||
end
|
||||
result.add_run
|
||||
yield(Test::Unit::TestCase::FINISHED, name)
|
||||
end
|
||||
|
||||
# Doubly unfortunate: mocha does the same so we have to hax their hax.
|
||||
def run_with_callbacks_and_mocha(result)
|
||||
return if @method_name.to_s == "default_test"
|
||||
|
||||
yield(Test::Unit::TestCase::STARTED, name)
|
||||
@_result = result
|
||||
begin
|
||||
mocha_setup
|
||||
module ForMiniTest
|
||||
def run(runner)
|
||||
result = '.'
|
||||
begin
|
||||
run_callbacks :setup
|
||||
setup
|
||||
__send__(@method_name)
|
||||
mocha_verify { add_assertion }
|
||||
rescue Mocha::ExpectationError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue StandardError, ScriptError
|
||||
add_error($!)
|
||||
result = super
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue StandardError, ScriptError
|
||||
add_error($!)
|
||||
rescue Exception => e
|
||||
result = runner.puke(self.class, self.name, e)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
mocha_teardown
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
module ForClassicTestUnit
|
||||
# For compatibility with Ruby < 1.8.6
|
||||
PASSTHROUGH_EXCEPTIONS = Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS rescue [NoMemoryError, SignalException, Interrupt, SystemExit]
|
||||
|
||||
# This redefinition is unfortunate but test/unit shows us no alternative.
|
||||
# Doubly unfortunate: hax to support Mocha's hax.
|
||||
def run(result)
|
||||
return if @method_name.to_s == "default_test"
|
||||
|
||||
if using_mocha = respond_to?(:mocha_verify)
|
||||
assertion_counter_klass = if defined?(Mocha::TestCaseAdapter::AssertionCounter)
|
||||
Mocha::TestCaseAdapter::AssertionCounter
|
||||
else
|
||||
Mocha::Integration::TestUnit::AssertionCounter
|
||||
end
|
||||
assertion_counter = assertion_counter_klass.new(result)
|
||||
end
|
||||
|
||||
yield(Test::Unit::TestCase::STARTED, name)
|
||||
@_result = result
|
||||
begin
|
||||
begin
|
||||
run_callbacks :setup
|
||||
setup
|
||||
__send__(@method_name)
|
||||
mocha_verify(assertion_counter) if using_mocha
|
||||
rescue Mocha::ExpectationError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue Exception => e
|
||||
raise if PASSTHROUGH_EXCEPTIONS.include?(e.class)
|
||||
add_error(e)
|
||||
ensure
|
||||
begin
|
||||
teardown
|
||||
run_callbacks :teardown, :enumerator => :reverse_each
|
||||
rescue Test::Unit::AssertionFailedError => e
|
||||
add_failure(e.message, e.backtrace)
|
||||
rescue Exception => e
|
||||
raise if PASSTHROUGH_EXCEPTIONS.include?(e.class)
|
||||
add_error(e)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
mocha_teardown if using_mocha
|
||||
end
|
||||
result.add_run
|
||||
yield(Test::Unit::TestCase::FINISHED, name)
|
||||
end
|
||||
result.add_run
|
||||
yield(Test::Unit::TestCase::FINISHED, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
require 'tzinfo'
|
||||
|
||||
module ActiveSupport
|
||||
# A Time-like class that can represent a time in any time zone. Necessary because standard Ruby Time instances are
|
||||
# limited to UTC and the system's <tt>ENV['TZ']</tt> zone.
|
||||
|
|
@ -98,28 +99,33 @@ module ActiveSupport
|
|||
"#{time.strftime('%a, %d %b %Y %H:%M:%S')} #{zone} #{formatted_offset}"
|
||||
end
|
||||
|
||||
def xmlschema
|
||||
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{formatted_offset(true, 'Z')}"
|
||||
def xmlschema(fraction_digits = 0)
|
||||
fraction = if fraction_digits > 0
|
||||
".%i" % time.usec.to_s[0, fraction_digits]
|
||||
end
|
||||
|
||||
"#{time.strftime("%Y-%m-%dT%H:%M:%S")}#{fraction}#{formatted_offset(true, 'Z')}"
|
||||
end
|
||||
alias_method :iso8601, :xmlschema
|
||||
|
||||
# Returns a JSON string representing the TimeWithZone. If ActiveSupport.use_standard_json_time_format is set to
|
||||
# true, the ISO 8601 format is used.
|
||||
# Coerces the date to a string for JSON encoding.
|
||||
#
|
||||
# ==== Examples:
|
||||
# ISO 8601 format is used if ActiveSupport::JSON::Encoding.use_standard_json_time_format is set.
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = true
|
||||
# ==== Examples
|
||||
#
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
|
||||
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
|
||||
# # => "2005-02-01T15:15:10Z"
|
||||
#
|
||||
# # With ActiveSupport.use_standard_json_time_format = false
|
||||
# # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false
|
||||
# Time.utc(2005,2,1,15,15,10).in_time_zone.to_json
|
||||
# # => "2005/02/01 15:15:10 +0000"
|
||||
def to_json(options = nil)
|
||||
if ActiveSupport.use_standard_json_time_format
|
||||
xmlschema.inspect
|
||||
def as_json(options = nil)
|
||||
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
|
||||
xmlschema
|
||||
else
|
||||
%("#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}")
|
||||
%(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -150,6 +156,7 @@ module ActiveSupport
|
|||
"#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby 1.9 Time#to_s format
|
||||
end
|
||||
end
|
||||
alias_method :to_formatted_s, :to_s
|
||||
|
||||
# Replaces <tt>%Z</tt> and <tt>%z</tt> directives with +zone+ and +formatted_offset+, respectively, before passing to
|
||||
# Time#strftime, so that zone information is correct
|
||||
|
|
@ -198,7 +205,7 @@ module ActiveSupport
|
|||
# If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
|
||||
# otherwise move backwards #utc, for accuracy when moving across DST boundaries
|
||||
if other.acts_like?(:time)
|
||||
utc - other
|
||||
utc.to_f - other.to_f
|
||||
elsif duration_of_variable_length?(other)
|
||||
method_missing(:-, other)
|
||||
else
|
||||
|
|
@ -224,7 +231,7 @@ module ActiveSupport
|
|||
def advance(options)
|
||||
# If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time,
|
||||
# otherwise advance from #utc, for accuracy when moving across DST boundaries
|
||||
if options.detect {|k,v| [:years, :weeks, :months, :days].include? k}
|
||||
if options.values_at(:years, :weeks, :months, :days).any?
|
||||
method_missing(:advance, options)
|
||||
else
|
||||
utc.advance(options).in_time_zone(time_zone)
|
||||
|
|
@ -233,9 +240,9 @@ module ActiveSupport
|
|||
|
||||
%w(year mon month day mday wday yday hour min sec to_date).each do |method_name|
|
||||
class_eval <<-EOV
|
||||
def #{method_name}
|
||||
time.#{method_name}
|
||||
end
|
||||
def #{method_name} # def year
|
||||
time.#{method_name} # time.year
|
||||
end # end
|
||||
EOV
|
||||
end
|
||||
|
||||
|
|
@ -322,7 +329,7 @@ module ActiveSupport
|
|||
end
|
||||
|
||||
def duration_of_variable_length?(obj)
|
||||
ActiveSupport::Duration === obj && obj.parts.flatten.detect {|p| [:years, :months, :days].include? p }
|
||||
ActiveSupport::Duration === obj && obj.parts.any? {|p| [:years, :months, :days].include? p[0] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ module ActiveSupport
|
|||
|
||||
# TODO: Preload instead of lazy load for thread safety
|
||||
def tzinfo
|
||||
require 'tzinfo' unless defined?(TZInfo)
|
||||
@tzinfo ||= TZInfo::Timezone.get(MAPPING[name])
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -6,17 +6,12 @@ begin
|
|||
rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/builder-2.1.2"
|
||||
end
|
||||
require 'builder'
|
||||
|
||||
begin
|
||||
gem 'xml-simple', '~> 1.0.11'
|
||||
gem 'memcache-client', '>= 1.7.4'
|
||||
rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/xml-simple-1.0.11"
|
||||
end
|
||||
|
||||
begin
|
||||
gem 'memcache-client', '~> 1.5.1'
|
||||
rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.5.1"
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/memcache-client-1.7.4"
|
||||
end
|
||||
|
||||
begin
|
||||
|
|
@ -25,10 +20,9 @@ rescue Gem::LoadError
|
|||
$:.unshift "#{File.dirname(__FILE__)}/vendor/tzinfo-0.3.12"
|
||||
end
|
||||
|
||||
# TODO I18n gem has not been released yet
|
||||
# begin
|
||||
# gem 'i18n', '~> 0.0.1'
|
||||
# rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.0.1"
|
||||
require 'i18n'
|
||||
# end
|
||||
begin
|
||||
gem 'i18n', '>= 0.1.3'
|
||||
rescue Gem::LoadError
|
||||
$:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.1.3/lib"
|
||||
end
|
||||
require 'i18n'
|
||||
|
|
|
|||
20
vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
vendored
Executable file
20
vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE
vendored
Executable file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2008 The Ruby I18n team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
20
vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
vendored
Normal file
20
vendor/rails/activesupport/lib/active_support/vendor/i18n-0.1.3/README.textile
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
h1. Ruby I18n gem
|
||||
|
||||
I18n and localization solution for Ruby.
|
||||
|
||||
For information please refer to http://rails-i18n.org
|
||||
|
||||
h2. Authors
|
||||
|
||||
* "Matt Aimonetti":http://railsontherun.com
|
||||
* "Sven Fuchs":http://www.artweb-design.de
|
||||
* "Joshua Harvey":http://www.workingwithrails.com/person/759-joshua-harvey
|
||||
* "Saimon Moore":http://saimonmoore.net
|
||||
* "Stephan Soller":http://www.arkanis-development.de
|
||||
|
||||
h2. License
|
||||
|
||||
MIT License. See the included MIT-LICENCE file.
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue