Merge commit 'rails/master'

Conflicts:

	activerecord/lib/active_record.rb

Updated:
  Arel submodule
This commit is contained in:
Emilio Tagua
2009-05-18 20:01:06 -03:00
20 changed files with 100 additions and 18 deletions

View File

@@ -194,9 +194,10 @@ module ActionController
if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque]
password = password_procedure.call(credentials[:username])
method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
[true, false].any? do |password_is_ha1|
expected = expected_response(request.env['REQUEST_METHOD'], request.env['REQUEST_URI'], credentials, password, password_is_ha1)
expected = expected_response(method, request.env['REQUEST_URI'], credentials, password, password_is_ha1)
expected == credentials[:response]
end
end

View File

@@ -1,5 +1,6 @@
require 'cgi'
require 'action_view/helpers/form_helper'
require 'active_support/core_ext/class/attribute_accessors'
module ActionView
class Base

View File

@@ -34,12 +34,16 @@ module ActionView
# Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
# (defaults to 30). The last characters will be replaced with the <tt>:omission</tt> (defaults to "...").
# Pass a <tt>:separator</tt> to truncate +text+ at a natural break.
#
# ==== Examples
#
# truncate("Once upon a time in a world far far away")
# # => Once upon a time in a world f...
#
# truncate("Once upon a time in a world far far away", :separator => ' ')
# # => Once upon a time in a world...
#
# truncate("Once upon a time in a world far far away", :length => 14)
# # => Once upon a...
#
@@ -71,7 +75,8 @@ module ActionView
if text
l = options[:length] - options[:omission].mb_chars.length
chars = text.mb_chars
(chars.length > options[:length] ? chars[0...l] + options[:omission] : text).to_s
stop = options[:separator] ? (chars.rindex(options[:separator].mb_chars, l) || l) : l
(chars.length > options[:length] ? chars[0...stop] + options[:omission] : text).to_s
end
end

View File

@@ -1,4 +1,5 @@
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
require 'active_support/core_ext/class/removal'
module AbstractControllerTests
module Layouts

View File

@@ -149,6 +149,16 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
assert_equal 'Definitely Maybe', @response.body
end
test "authentication request with _method" do
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please', :method => :post)
@request.env['rack.methodoverride.original_method'] = 'POST'
put :display
assert_response :success
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
private
def encode_credentials(options)
@@ -159,15 +169,22 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
# to prevent tampering of timestamp
ActionController::Base.session_options[:secret] = "session_options_secret"
# Perform unauthenticated GET to retrieve digest parameters to use on subsequent request
get :index
# Perform unauthenticated request to retrieve digest parameters to use on subsequent request
method = options.delete(:method) || 'GET'
case method.to_s.upcase
when 'GET'
get :index
when 'POST'
post :index
end
assert_response :unauthorized
credentials = decode_credentials(@response.headers['WWW-Authenticate'])
credentials.merge!(options)
credentials.reverse_merge!(:uri => "#{@request.env['REQUEST_URI']}")
ActionController::HttpAuthentication::Digest.encode_credentials("GET", credentials, password, options[:password_is_ha1])
ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1])
end
def decode_credentials(header)

View File

@@ -49,6 +49,9 @@ class TextHelperTest < ActionView::TestCase
assert_equal "This is a string that wil[...]", truncate("This is a string that will go longer then the default truncate length of 30", :omission => "[...]")
assert_equal "Hello W...", truncate("Hello World!", :length => 10)
assert_equal "Hello[...]", truncate("Hello World!", :omission => "[...]", :length => 10)
assert_equal "Hello[...]", truncate("Hello Big World!", :omission => "[...]", :length => 13, :separator => ' ')
assert_equal "Hello Big[...]", truncate("Hello Big World!", :omission => "[...]", :length => 14, :separator => ' ')
assert_equal "Hello Big[...]", truncate("Hello Big World!", :omission => "[...]", :length => 15, :separator => ' ')
end
if RUBY_VERSION < '1.9.0'

View File

@@ -25,9 +25,6 @@ activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
$:.unshift(activesupport_path) if File.directory?(activesupport_path)
require 'active_support'
# TODO: Figure out what parts of AS are *actually* required and use those
require 'active_support/core_ext'
$:.unshift(File.dirname(__FILE__) + '/../../arel/lib')
require 'arel'

View File

@@ -17,6 +17,13 @@ module ActiveRecord
end
end
def destroy(*records)
transaction do
delete_records(flatten_deeper(records))
super
end
end
# Returns the size of the collection by executing a SELECT COUNT(*) query if the collection hasn't been loaded and
# calling collection.size if it has. If it's more likely than not that the collection does have a size larger than zero,
# and you need to fetch that collection afterwards, it'll take one fewer SELECT query if you use #length.

View File

@@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/deep_merge'
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/behavior'
require 'active_support/core_ext/symbol'
require 'active_support/core/time'
module ActiveRecord #:nodoc:
@@ -1539,12 +1540,12 @@ module ActiveRecord #:nodoc:
end
def reverse_sql_order(order_query)
reversed_query = order_query.to_s.split(/,/).each { |s|
order_query.to_s.split(/,/).each { |s|
if s.match(/\s(asc|ASC)$/)
s.gsub!(/\s(asc|ASC)$/, ' DESC')
elsif s.match(/\s(desc|DESC)$/)
s.gsub!(/\s(desc|DESC)$/, ' ASC')
elsif !s.match(/\s(asc|ASC|desc|DESC)$/)
else
s.concat(' DESC')
end
}.join(',')
@@ -2244,7 +2245,7 @@ module ActiveRecord #:nodoc:
# default_scope :order => 'last_name, first_name'
# end
def default_scope(options = {})
self.default_scoping << { :find => options, :create => (options.is_a?(Hash) && options.has_key?(:conditions)) ? options[:conditions] : {} }
self.default_scoping << { :find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {} }
end
# Test whether the given method and optional key are scoped.

View File

@@ -1,6 +1,7 @@
require 'erb'
require 'yaml'
require 'csv'
require 'zlib'
require 'active_support/dependencies'
require 'active_support/test_case'
require 'active_support/core_ext/logger'
@@ -434,6 +435,7 @@ end
# Any fixture labeled "DEFAULTS" is safely ignored.
class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
MAX_ID = 2 ** 31 - 1
DEFAULT_FILTER_RE = /\.ya?ml$/
@@all_cached_fixtures = {}
@@ -525,11 +527,10 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
cached_fixtures(connection, table_names)
end
# Returns a consistent identifier for +label+. This will always
# be a positive integer, and will always be the same for a given
# label, assuming the same OS, platform, and version of Ruby.
# Returns a consistent, platform-independent identifier for +label+.
# Identifiers are positive integers less than 2^32.
def self.identify(label)
label.to_s.hash.abs
Zlib.crc32(label.to_s) % MAX_ID
end
attr_reader :table_name, :name

View File

@@ -1,3 +1,5 @@
require 'active_support/core_ext/integer/even_odd'
module ActiveRecord
# Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
# +record+ method to retrieve the record which did not validate.

View File

@@ -93,7 +93,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_destroy_association
assert_difference "Person.count", -1 do
assert_difference ["Person.count", "Reader.count"], -1 do
posts(:welcome).people.destroy(people(:michael))
end
@@ -102,7 +102,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
end
def test_destroy_all
assert_difference "Person.count", -1 do
assert_difference ["Person.count", "Reader.count"], -1 do
posts(:welcome).people.destroy_all
end
@@ -110,6 +110,12 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
assert posts(:welcome).people(true).empty?
end
def test_should_raise_exception_for_destroying_mismatching_records
assert_no_difference ["Person.count", "Reader.count"] do
assert_raise(ActiveRecord::AssociationTypeMismatch) { posts(:welcome).people.destroy(posts(:thinking)) }
end
end
def test_replace_association
assert_queries(4){posts(:welcome);people(:david);people(:michael); posts(:welcome).people(true)}

View File

@@ -518,6 +518,11 @@ class FoxyFixturesTest < ActiveRecord::TestCase
assert_equal(Fixtures.identify(:foo), Fixtures.identify(:foo))
end
def test_identifies_consistently
assert_equal 1281023246, Fixtures.identify(:ruby)
assert_equal 2140105598, Fixtures.identify(:sapphire_2)
end
TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on)
def test_populates_timestamp_columns

View File

@@ -591,6 +591,16 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal expected, received
end
def test_default_scope_with_conditions_string
assert_equal Developer.find_all_by_name('David').map(&:id).sort, DeveloperCalledDavid.all.map(&:id).sort
assert_equal nil, DeveloperCalledDavid.create!.name
end
def test_default_scope_with_conditions_hash
assert_equal Developer.find_all_by_name('Jamis').map(&:id).sort, DeveloperCalledJamis.all.map(&:id).sort
assert_equal 'Jamis', DeveloperCalledJamis.create!.name
end
def test_default_scoping_with_threads
scope = [{ :create => {}, :find => { :order => 'salary DESC' } }]

View File

@@ -89,3 +89,13 @@ class DeveloperOrderedBySalary < ActiveRecord::Base
end
end
end
class DeveloperCalledDavid < ActiveRecord::Base
self.table_name = 'developers'
default_scope :conditions => "name = 'David'"
end
class DeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
default_scope :conditions => { :name => 'Jamis' }
end

View File

@@ -43,6 +43,11 @@ module ActiveSupport
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:
super
@data.get(key, raw?(options))

View File

@@ -1,4 +1,5 @@
# encoding: utf-8
require 'active_support/core_ext/string/behavior'
module ActiveSupport #:nodoc:
module Multibyte #:nodoc:

View File

View File

@@ -251,6 +251,15 @@ uses_memcached 'memcached backed store' do
end
end
def test_multi_get
@cache.with_local_cache do
@cache.write('foo', 1)
@cache.write('goo', 2)
result = @cache.read_multi('foo', 'goo')
assert_equal({'foo' => 1, 'goo' => 2}, result)
end
end
def test_middleware
app = lambda { |env|
result = @cache.write('foo', 'bar')

2
arel

Submodule arel updated: a7dea38204...4b8526dddd