mirror of
https://github.com/github/rails.git
synced 2026-01-14 00:58:04 -05:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
730e6a273c | ||
|
|
aa1b6d1284 | ||
|
|
5f6c95e29e | ||
|
|
7403667b89 | ||
|
|
1a45ec57bf | ||
|
|
9070fbcffe | ||
|
|
364b534815 | ||
|
|
14da203564 | ||
|
|
f46a4bab08 | ||
|
|
198aa6ef99 | ||
|
|
b3ae51c9fc | ||
|
|
1e6e438f6e | ||
|
|
2b01f832a3 | ||
|
|
1e5fda763e | ||
|
|
7c3d4ec43c | ||
|
|
7343ed7b05 | ||
|
|
2a70c9691d | ||
|
|
a141d9de0d | ||
|
|
74492f43a8 | ||
|
|
c2894170bf | ||
|
|
057aed6e18 | ||
|
|
02fc012b42 | ||
|
|
4fdaf21b28 | ||
|
|
35b871fbcd | ||
|
|
a5697840d6 | ||
|
|
d0e554d231 | ||
|
|
d38b7664cc | ||
|
|
e4cd9caf02 | ||
|
|
89e4514704 | ||
|
|
0a0d975f51 | ||
|
|
62daf4cb6f | ||
|
|
24711e1e29 |
@@ -1 +1 @@
|
|||||||
2.3.14.github36
|
2.3.14.github45
|
||||||
|
|||||||
@@ -1320,7 +1320,14 @@ module ActionController #:nodoc:
|
|||||||
render
|
render
|
||||||
end
|
end
|
||||||
|
|
||||||
|
CVE_2014_0310 = Class.new(StandardError)
|
||||||
|
|
||||||
def perform_action
|
def perform_action
|
||||||
|
# CVE-2014-0130 protection
|
||||||
|
if action_name.include? "/"
|
||||||
|
raise CVE_2014_0310
|
||||||
|
end
|
||||||
|
|
||||||
if action_methods.include?(action_name)
|
if action_methods.include?(action_name)
|
||||||
send(action_name)
|
send(action_name)
|
||||||
default_render unless performed?
|
default_render unless performed?
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ module ActionController #:nodoc:
|
|||||||
log_message << " [#{complete_request_uri rescue "unknown"}]"
|
log_message << " [#{complete_request_uri rescue "unknown"}]"
|
||||||
|
|
||||||
logger.info(log_message)
|
logger.info(log_message)
|
||||||
response.headers["X-Runtime"] = "%.0f" % ms
|
|
||||||
else
|
else
|
||||||
perform_action_without_benchmark
|
perform_action_without_benchmark
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -45,37 +45,74 @@ module ActionController #:nodoc:
|
|||||||
end
|
end
|
||||||
|
|
||||||
def []=(k, v)
|
def []=(k, v)
|
||||||
|
k = k.to_s
|
||||||
@flash[k] = v
|
@flash[k] = v
|
||||||
@flash.discard(k)
|
@flash.discard(k)
|
||||||
v
|
v
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](k)
|
def [](k)
|
||||||
@flash[k]
|
@flash[k.to_s]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class FlashHash < Hash
|
class FlashHash < Hash
|
||||||
|
def self.from_session_value(value)
|
||||||
|
flash = case value
|
||||||
|
when FlashHash # Rails 2.3
|
||||||
|
value
|
||||||
|
when Hash # Rails 4.0
|
||||||
|
flashes = value['flashes'] || {}
|
||||||
|
flashes.stringify_keys!
|
||||||
|
discard = value['discard'] || []
|
||||||
|
discard = discard.map do |item|
|
||||||
|
item.kind_of?(Symbol) ? item.to_s : item
|
||||||
|
end
|
||||||
|
used = Hash[flashes.keys.map{|k| [k, discard.include?(k)] }]
|
||||||
|
|
||||||
|
new_from_values(flashes, used)
|
||||||
|
else
|
||||||
|
new
|
||||||
|
end
|
||||||
|
flash
|
||||||
|
end
|
||||||
|
|
||||||
def initialize #:nodoc:
|
def initialize #:nodoc:
|
||||||
super
|
super
|
||||||
@used = {}
|
@used = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_session_value
|
||||||
|
return nil if empty?
|
||||||
|
rails_3_discard_list = @used.map{|k,v| k if v}.compact
|
||||||
|
{'discard' => rails_3_discard_list, 'flashes' => Hash[to_a]}
|
||||||
|
end
|
||||||
|
|
||||||
def []=(k, v) #:nodoc:
|
def []=(k, v) #:nodoc:
|
||||||
|
k = k.to_s
|
||||||
keep(k)
|
keep(k)
|
||||||
super
|
super(k, v)
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](k)
|
||||||
|
super(k.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(k)
|
||||||
|
super(k.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(h) #:nodoc:
|
def update(h) #:nodoc:
|
||||||
|
h.stringify_keys!
|
||||||
h.keys.each { |k| keep(k) }
|
h.keys.each { |k| keep(k) }
|
||||||
super
|
super(h)
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :merge! :update
|
alias :merge! :update
|
||||||
|
|
||||||
def replace(h) #:nodoc:
|
def replace(h) #:nodoc:
|
||||||
@used = {}
|
@used = {}
|
||||||
super
|
super(h.stringify_keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets a flash that will not be available to the next action, only to the current.
|
# Sets a flash that will not be available to the next action, only to the current.
|
||||||
@@ -126,8 +163,7 @@ module ActionController #:nodoc:
|
|||||||
end
|
end
|
||||||
|
|
||||||
def store(session, key = "flash")
|
def store(session, key = "flash")
|
||||||
return if self.empty?
|
session[key] = to_session_value
|
||||||
session[key] = self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -138,11 +174,20 @@ module ActionController #:nodoc:
|
|||||||
# use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
|
# use('msg', false) # marks the "msg" entry as unused (keeps it around for one more action)
|
||||||
def use(k=nil, v=true)
|
def use(k=nil, v=true)
|
||||||
unless k.nil?
|
unless k.nil?
|
||||||
@used[k] = v
|
@used[k.to_s] = v
|
||||||
else
|
else
|
||||||
keys.each{ |key| use(key, v) }
|
keys.each{ |key| use(key, v) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.new_from_values(flashes, used)
|
||||||
|
new.tap do |flash_hash|
|
||||||
|
flashes.each do |k, v|
|
||||||
|
flash_hash[k] = v
|
||||||
|
end
|
||||||
|
flash_hash.instance_variable_set("@used", used)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods #:nodoc:
|
module InstanceMethods #:nodoc:
|
||||||
@@ -181,7 +226,7 @@ module ActionController #:nodoc:
|
|||||||
# to put a new one.
|
# to put a new one.
|
||||||
def flash #:doc:
|
def flash #:doc:
|
||||||
if !defined?(@_flash)
|
if !defined?(@_flash)
|
||||||
@_flash = session["flash"] || FlashHash.new
|
@_flash = Flash::FlashHash.from_session_value(session["flash"])
|
||||||
@_flash.sweep
|
@_flash.sweep
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -55,17 +55,17 @@ module ActionController
|
|||||||
|
|
||||||
def [](key)
|
def [](key)
|
||||||
load_for_read!
|
load_for_read!
|
||||||
super
|
super(key.to_s) || super(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_key?(key)
|
def has_key?(key)
|
||||||
load_for_read!
|
load_for_read!
|
||||||
super
|
super(key.to_s) || super(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
def []=(key, value)
|
def []=(key, value)
|
||||||
load_for_write!
|
load_for_write!
|
||||||
super
|
super(key.to_s, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
def clear
|
def clear
|
||||||
@@ -87,7 +87,9 @@ module ActionController
|
|||||||
|
|
||||||
def delete(key)
|
def delete(key)
|
||||||
load_for_write!
|
load_for_write!
|
||||||
super
|
value = super(key)
|
||||||
|
string_value = super(key.to_s)
|
||||||
|
string_value || value
|
||||||
end
|
end
|
||||||
|
|
||||||
def data
|
def data
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ module ActionController
|
|||||||
@secret = options.delete(:secret).freeze
|
@secret = options.delete(:secret).freeze
|
||||||
|
|
||||||
@digest = options.delete(:digest) || 'SHA1'
|
@digest = options.delete(:digest) || 'SHA1'
|
||||||
@verifier = verifier_for(@secret, @digest)
|
@serializer = options.delete(:serializer) || Marshal
|
||||||
|
@verifier = verifier_for(@secret, @digest, @serializer)
|
||||||
|
|
||||||
@default_options = DEFAULT_OPTIONS.merge(options).freeze
|
@default_options = DEFAULT_OPTIONS.merge(options).freeze
|
||||||
|
|
||||||
@@ -103,6 +104,13 @@ module ActionController
|
|||||||
request = ActionController::Request.new(env)
|
request = ActionController::Request.new(env)
|
||||||
|
|
||||||
if !(options[:secure] && !request.ssl?) && (!session_data.is_a?(AbstractStore::SessionHash) || session_data.loaded? || options[:expire_after])
|
if !(options[:secure] && !request.ssl?) && (!session_data.is_a?(AbstractStore::SessionHash) || session_data.loaded? || options[:expire_after])
|
||||||
|
|
||||||
|
# Backport standard Rack::Session::Cookie behavior
|
||||||
|
# Skip writing session if env['rack.session.options'][:skip] is set
|
||||||
|
if options[:skip]
|
||||||
|
return [status, headers, body]
|
||||||
|
end
|
||||||
|
|
||||||
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
|
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
|
||||||
|
|
||||||
persistent_session_id!(session_data)
|
persistent_session_id!(session_data)
|
||||||
@@ -131,13 +139,13 @@ module ActionController
|
|||||||
def load_session(env)
|
def load_session(env)
|
||||||
data = unpacked_cookie_data(env)
|
data = unpacked_cookie_data(env)
|
||||||
data = persistent_session_id!(data)
|
data = persistent_session_id!(data)
|
||||||
[data[:session_id], data]
|
[data["session_id"] || data[:session_id], data]
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_session_id(env)
|
def extract_session_id(env)
|
||||||
if data = unpacked_cookie_data(env)
|
if data = unpacked_cookie_data(env)
|
||||||
persistent_session_id!(data) unless data.empty?
|
persistent_session_id!(data) unless data.empty?
|
||||||
data[:session_id]
|
data["session_id"] || data[:session_id]
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
@@ -207,9 +215,9 @@ module ActionController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def verifier_for(secret, digest)
|
def verifier_for(secret, digest, serializer)
|
||||||
key = secret.respond_to?(:call) ? secret.call : secret
|
key = secret.respond_to?(:call) ? secret.call : secret
|
||||||
ActiveSupport::MessageVerifier.new(key, digest: digest)
|
ActiveSupport::MessageVerifier.new(key, digest: digest, serializer: serializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_sid
|
def generate_sid
|
||||||
@@ -225,12 +233,12 @@ module ActionController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def inject_persistent_session_id(data)
|
def inject_persistent_session_id(data)
|
||||||
requires_session_id?(data) ? { :session_id => generate_sid } : {}
|
requires_session_id?(data) ? { "session_id" => generate_sid } : {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def requires_session_id?(data)
|
def requires_session_id?(data)
|
||||||
if data
|
if data
|
||||||
data.respond_to?(:key?) && !data.key?(:session_id)
|
data.respond_to?(:key?) && !(data.key?("session_id") || data.key?(:session_id))
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ module ActionController #:nodoc:
|
|||||||
|
|
||||||
# A shortcut to the flash. Returns an empty hash if no session flash exists.
|
# A shortcut to the flash. Returns an empty hash if no session flash exists.
|
||||||
def flash
|
def flash
|
||||||
session['flash'] || {}
|
ActionController::Flash::FlashHash.from_session_value(session["flash"]) || {}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Do we have a flash?
|
# Do we have a flash?
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ module ActionView
|
|||||||
def number_to_currency(number, options = {})
|
def number_to_currency(number, options = {})
|
||||||
options.symbolize_keys!
|
options.symbolize_keys!
|
||||||
|
|
||||||
|
options[:format] = ERB::Util.html_escape(options[:format]) if options[:format]
|
||||||
|
|
||||||
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
||||||
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
|
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
|
||||||
defaults = defaults.merge(currency)
|
defaults = defaults.merge(currency)
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ require 'abstract_unit'
|
|||||||
class NumberHelperTest < ActionView::TestCase
|
class NumberHelperTest < ActionView::TestCase
|
||||||
tests ActionView::Helpers::NumberHelper
|
tests ActionView::Helpers::NumberHelper
|
||||||
|
|
||||||
|
def test_number_helpers_escape_delimiter_and_separator
|
||||||
|
assert_equal "$1<script></script>01", number_to_currency(1.01, :separator => "<script></script>")
|
||||||
|
assert_equal "$1<script></script>000.00", number_to_currency(1000, :delimiter => "<script></script>")
|
||||||
|
assert_equal "<script>1,000.00$</script>", number_to_currency(1000, :format => "<script>%n%u</script>")
|
||||||
|
end
|
||||||
|
|
||||||
def test_number_to_phone
|
def test_number_to_phone
|
||||||
assert_equal("555-1234", number_to_phone(5551234))
|
assert_equal("555-1234", number_to_phone(5551234))
|
||||||
assert_equal("800-555-1212", number_to_phone(8005551212))
|
assert_equal("800-555-1212", number_to_phone(8005551212))
|
||||||
|
|||||||
@@ -195,7 +195,9 @@ module ActiveRecord
|
|||||||
def log_info(sql, name, ms)
|
def log_info(sql, name, ms)
|
||||||
if @logger && @logger.debug?
|
if @logger && @logger.debug?
|
||||||
name = '%s (%.1fms)' % [name || 'SQL', ms]
|
name = '%s (%.1fms)' % [name || 'SQL', ms]
|
||||||
sql.force_encoding 'binary' if sql.respond_to?(:force_encoding)
|
if sql.respond_to?(:force_encoding)
|
||||||
|
sql = sql.dup.force_encoding 'binary'
|
||||||
|
end
|
||||||
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
|
@logger.debug(format_log_entry(name, sql.squeeze(' ')))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -212,13 +214,7 @@ module ActiveRecord
|
|||||||
log_info(sql, name, 0)
|
log_info(sql, name, 0)
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
rescue SystemExit, SignalException, NoMemoryError => e
|
rescue => e
|
||||||
# Don't re-wrap these exceptions. They are probably not being caused by invalid
|
|
||||||
# sql, but rather some external stimulus beyond the responsibilty of this code.
|
|
||||||
# Additionaly, wrapping these exceptions with StatementInvalid would lead to
|
|
||||||
# meaningful loss of data, such as losing SystemExit#status.
|
|
||||||
raise e
|
|
||||||
rescue Exception => e
|
|
||||||
# Log message and raise exception.
|
# Log message and raise exception.
|
||||||
# Set last_verification to 0, so that connection gets verified
|
# Set last_verification to 0, so that connection gets verified
|
||||||
# upon reentering the request loop
|
# upon reentering the request loop
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
require 'active_support/core_ext/kernel/daemonizing'
|
require 'active_support/core_ext/kernel/daemonizing'
|
||||||
require 'active_support/core_ext/kernel/reporting'
|
require 'active_support/core_ext/kernel/reporting'
|
||||||
require 'active_support/core_ext/kernel/agnostics'
|
|
||||||
require 'active_support/core_ext/kernel/requires'
|
require 'active_support/core_ext/kernel/requires'
|
||||||
require 'active_support/core_ext/kernel/debugger'
|
require 'active_support/core_ext/kernel/debugger'
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
class Object
|
|
||||||
# Makes backticks behave (somewhat more) similarly on all platforms.
|
|
||||||
# On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
|
|
||||||
# spawned shell prints a message to stderr and sets $?. We emulate
|
|
||||||
# Unix on the former but not the latter.
|
|
||||||
def `(command) #:nodoc:
|
|
||||||
super
|
|
||||||
rescue Errno::ENOENT => e
|
|
||||||
STDERR.puts "#$0: #{e}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
require 'active_support/core_ext/kernel/singleton_class'
|
||||||
|
require 'active_support/core_ext/module/aliasing'
|
||||||
|
|
||||||
module ActiveSupport
|
module ActiveSupport
|
||||||
module Memoizable
|
module Memoizable
|
||||||
def self.memoized_ivar_for(symbol)
|
def self.memoized_ivar_for(symbol)
|
||||||
@@ -41,10 +44,10 @@ module ActiveSupport
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def flush_cache(*syms, &block)
|
def flush_cache(*syms)
|
||||||
syms.each do |sym|
|
syms.each do |sym|
|
||||||
(methods + private_methods + protected_methods).each do |m|
|
(methods + private_methods + protected_methods).each do |m|
|
||||||
if m.to_s =~ /^_unmemoized_(#{sym})/
|
if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/
|
||||||
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
|
ivar = ActiveSupport::Memoizable.memoized_ivar_for($1)
|
||||||
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
|
instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
|
||||||
end
|
end
|
||||||
@@ -69,7 +72,7 @@ module ActiveSupport
|
|||||||
if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
|
if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0
|
||||||
def #{symbol}(reload = false) # def mime_type(reload = false)
|
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?
|
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]
|
#{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type]
|
||||||
end # end
|
end # end
|
||||||
#{memoized_ivar}[0] # @_memoized_mime_type[0]
|
#{memoized_ivar}[0] # @_memoized_mime_type[0]
|
||||||
end # end
|
end # end
|
||||||
@@ -82,7 +85,7 @@ module ActiveSupport
|
|||||||
if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
|
if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args)
|
||||||
#{memoized_ivar}[args] # @_memoized_mime_type[args]
|
#{memoized_ivar}[args] # @_memoized_mime_type[args]
|
||||||
elsif #{memoized_ivar} # elsif @_memoized_mime_type
|
elsif #{memoized_ivar} # elsif @_memoized_mime_type
|
||||||
#{memoized_ivar}[args] = #{original_method}(*args).freeze # @_memoized_mime_type[args] = _unmemoized_mime_type(*args).freeze
|
#{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args)
|
||||||
end # end
|
end # end
|
||||||
else # else
|
else # else
|
||||||
#{original_method}(*args) # _unmemoized_mime_type(*args)
|
#{original_method}(*args) # _unmemoized_mime_type(*args)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
require 'abstract_unit'
|
||||||
require 'active_support'
|
require 'active_support'
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ class MemoizableTest < Test::Unit::TestCase
|
|||||||
class Person
|
class Person
|
||||||
extend ActiveSupport::Memoizable
|
extend ActiveSupport::Memoizable
|
||||||
|
|
||||||
attr_reader :name_calls, :age_calls, :is_developer_calls
|
attr_reader :name_calls, :age_calls, :is_developer_calls, :name_query_calls
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@name_calls = 0
|
@name_calls = 0
|
||||||
@age_calls = 0
|
@age_calls = 0
|
||||||
@is_developer_calls = 0
|
@is_developer_calls = 0
|
||||||
|
@name_query_calls = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
@@ -18,6 +19,7 @@ class MemoizableTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def name?
|
def name?
|
||||||
|
@name_query_calls += 1
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
memoize :name?
|
memoize :name?
|
||||||
@@ -123,6 +125,13 @@ class MemoizableTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_memoization_flush_with_punctuation
|
||||||
|
assert_equal true, @person.name?
|
||||||
|
@person.flush_cache(:name?)
|
||||||
|
3.times { assert_equal true, @person.name? }
|
||||||
|
assert_equal 2, @person.name_query_calls
|
||||||
|
end
|
||||||
|
|
||||||
def test_memoization_with_nil_value
|
def test_memoization_with_nil_value
|
||||||
assert_equal nil, @person.age
|
assert_equal nil, @person.age
|
||||||
assert_equal 1, @person.age_calls
|
assert_equal 1, @person.age_calls
|
||||||
@@ -131,13 +140,7 @@ class MemoizableTest < Test::Unit::TestCase
|
|||||||
assert_equal 1, @person.age_calls
|
assert_equal 1, @person.age_calls
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_memorized_results_are_immutable
|
|
||||||
assert_equal "Josh", @person.name
|
|
||||||
assert_raise(ActiveSupport::FrozenObjectError) { @person.name.gsub!("Josh", "Gosh") }
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_reloadable
|
def test_reloadable
|
||||||
counter = @calculator.counter
|
|
||||||
assert_equal 1, @calculator.counter
|
assert_equal 1, @calculator.counter
|
||||||
assert_equal 2, @calculator.counter(:reload)
|
assert_equal 2, @calculator.counter(:reload)
|
||||||
assert_equal 2, @calculator.counter
|
assert_equal 2, @calculator.counter
|
||||||
|
|||||||
Reference in New Issue
Block a user