Merge branch 'master' of github.com:rails/rails

This commit is contained in:
Xavier Noria
2011-01-12 21:19:10 +01:00
55 changed files with 522 additions and 303 deletions

View File

@@ -59,7 +59,7 @@ module ActionController #:nodoc:
key = fragment_cache_key(key)
instrument_fragment_cache :write_fragment, key do
content = content.html_safe.to_str if content.respond_to?(:html_safe)
content = content.to_str
cache_store.write(key, content, options)
end
content

View File

@@ -50,11 +50,11 @@ module ActionDispatch
# Only this middleware cares about RoutingError. So, let's just raise
# it here.
if headers['X-Cascade'] == 'pass'
exception = ActionController::RoutingError.new("No route matches #{env['PATH_INFO'].inspect}")
raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}"
end
rescue Exception => exception
raise exception if env['action_dispatch.show_exceptions'] == false
end
raise exception if env['action_dispatch.show_exceptions'] == false
exception ? render_exception(env, exception) : [status, headers, body]
end

View File

@@ -450,7 +450,7 @@ module ActionDispatch
end
def raise_routing_error
raise ActionController::RoutingError.new("No route matches #{options.inspect}")
raise ActionController::RoutingError, "No route matches #{options.inspect}"
end
def different_controller?

View File

@@ -156,10 +156,8 @@ module ActionView
# The instance of ActionView::Base that is used by +render+.
def view
@view ||= begin
view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
view = @controller.view_context
view.singleton_class.send :include, _helpers
view.singleton_class.send :include, @controller._routes.url_helpers
view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
view.extend(Locals)
view.locals = self.locals
view.output_buffer = self.output_buffer

View File

@@ -116,6 +116,27 @@ module ActionView
end
end
class ControllerHelperMethod < ActionView::TestCase
module SomeHelper
def some_method
render :partial => 'test/from_helper'
end
end
helper SomeHelper
test "can call a helper method defined on the current controller from a helper" do
@controller.singleton_class.class_eval <<-EOF, __FILE__, __LINE__ + 1
def render_from_helper
'controller_helper_method'
end
EOF
@controller.class.helper_method :render_from_helper
assert_equal 'controller_helper_method', some_method
end
end
class AssignsTest < ActionView::TestCase
setup do
ActiveSupport::Deprecation.stubs(:warn)

View File

@@ -41,7 +41,7 @@ namespace :test do
end
end
%w( mysql mysql2 postgresql sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
%w( mysql mysql2 postgresql sqlite3 sqlite3_mem firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
Rake::TestTask.new("test_#{adapter}") { |t|
connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z0-9]+/]

View File

@@ -126,21 +126,21 @@ module ActiveRecord
parent_records.each do |parent_record|
association_proxy = parent_record.send(reflection_name)
association_proxy.loaded
association_proxy.target.push(*Array.wrap(associated_record))
association_proxy.target.concat(Array.wrap(associated_record))
association_proxy.send(:set_inverse_instance, associated_record)
end
end
def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record)
parent_records.each do |parent_record|
parent_record.send("set_#{reflection_name}_target", associated_record)
parent_record.send(:association_proxy, reflection_name).target = associated_record
end
end
def set_association_collection_records(id_to_record_map, reflection_name, associated_records, key)
def set_association_collection_records(id_to_parent_map, reflection_name, associated_records, key)
associated_records.each do |associated_record|
mapped_records = id_to_record_map[associated_record[key].to_s]
add_preloaded_records_to_collection(mapped_records, reflection_name, associated_record)
parent_records = id_to_parent_map[associated_record[key].to_s]
add_preloaded_records_to_collection(parent_records, reflection_name, associated_record)
end
end
@@ -158,14 +158,17 @@ module ActiveRecord
seen_keys[seen_key] = true
mapped_records = id_to_record_map[seen_key]
mapped_records.each do |mapped_record|
association_proxy = mapped_record.send("set_#{reflection_name}_target", associated_record)
association_proxy = mapped_record.send(:association_proxy, reflection_name)
association_proxy.target = associated_record
association_proxy.send(:set_inverse_instance, associated_record)
end
end
id_to_record_map.each do |id, records|
next if seen_keys.include?(id.to_s)
records.each {|record| record.send("set_#{reflection_name}_target", nil) }
records.each do |record|
record.send(:association_proxy, reflection_name).target = nil
end
end
end
@@ -196,7 +199,6 @@ module ActiveRecord
right = Arel::Table.new(options[:join_table]).alias('t0')
join_condition = left[reflection.klass.primary_key].eq(
right[reflection.association_foreign_key])
@@ -218,24 +220,35 @@ module ActiveRecord
custom_conditions = append_conditions(reflection, preload_options)
all_associated_records = associated_records(ids) do |some_ids|
klass = associated_records_proxy.klass
associated_records(ids) { |some_ids|
method = in_or_equal(some_ids)
conditions = right[reflection.foreign_key].send(*method)
conditions = custom_conditions.inject(conditions) do |ast, cond|
ast.and cond
end
associated_records_proxy.where(conditions).to_a
end
set_association_collection_records(id_to_record_map, reflection.name, all_associated_records, 'the_parent_record_id')
relation = associated_records_proxy.where(conditions)
klass.connection.select_all(relation.arel.to_sql, 'SQL', relation.bind_values)
}.map! { |row|
parent_records = id_to_record_map[row['the_parent_record_id'].to_s]
associated_record = klass.instantiate row
add_preloaded_records_to_collection(
parent_records, reflection.name, associated_record)
associated_record
}
end
def preload_has_one_association(records, reflection, preload_options={})
return if records.first.send("loaded_#{reflection.name}?")
return if records.first.send(:association_proxy, reflection.name).loaded?
id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key])
options = reflection.options
records.each {|record| record.send("set_#{reflection.name}_target", nil)}
records.each do |record|
record.send(:association_proxy, reflection.name).target = nil
end
if options[:through]
through_records = preload_through_records(records, reflection, options[:through])
@@ -317,7 +330,7 @@ module ActiveRecord
end
def preload_belongs_to_association(records, reflection, preload_options={})
return if records.first.send("loaded_#{reflection.name}?")
return if records.first.send(:association_proxy, reflection.name).loaded?
options = reflection.options
klasses_and_ids = {}
@@ -415,7 +428,7 @@ module ActiveRecord
in_clause_length = connection.in_clause_length || ids.size
records = []
ids.each_slice(in_clause_length) do |some_ids|
records += yield(some_ids)
records.concat yield(some_ids)
end
records
end

View File

@@ -137,6 +137,22 @@ module ActiveRecord
# :nodoc:
attr_reader :association_cache
protected
# Returns the proxy for the given association name, instantiating it if it doesn't
# already exist
def association_proxy(name)
association = association_instance_get(name)
if association.nil?
reflection = self.class.reflect_on_association(name)
association = reflection.proxy_class.new(self, reflection)
association_instance_set(name, association)
end
association
end
private
# Returns the specified association instance if it responds to :loaded?, nil otherwise.
def association_instance_get(name)
@@ -332,26 +348,31 @@ module ActiveRecord
# === One-to-one associations
#
# * Assigning an object to a +has_one+ association automatically saves that object and
# the object being replaced (if there is one), in order to update their primary
# keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
# * If either of these saves fail (due to one of the objects being invalid) the assignment
# statement returns +false+ and the assignment is cancelled.
# the object being replaced (if there is one), in order to update their foreign
# keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
# * If either of these saves fail (due to one of the objects being invalid), an
# <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
# cancelled.
# * If you wish to assign an object to a +has_one+ association without saving it,
# use the <tt>association.build</tt> method (documented below).
# use the <tt>build_association</tt> method (documented below). The object being
# replaced will still be saved to update its foreign key.
# * Assigning an object to a +belongs_to+ association does not save the object, since
# the foreign key field belongs on the parent. It does not save the parent either.
# the foreign key field belongs on the parent. It does not save the parent either.
#
# === Collections
#
# * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
# saves that object, except if the parent object (the owner of the collection) is not yet
# stored in the database.
# saves that object, except if the parent object (the owner of the collection) is not yet
# stored in the database.
# * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
# fails, then <tt>push</tt> returns +false+.
# fails, then <tt>push</tt> returns +false+.
# * If saving fails while replacing the collection (via <tt>association=</tt>), an
# <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
# cancelled.
# * You can add an object to a collection without automatically saving it by using the
# <tt>collection.build</tt> method (documented below).
# <tt>collection.build</tt> method (documented below).
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
# saved when the parent is saved.
# saved when the parent is saved.
#
# === Association callbacks
#
@@ -998,12 +1019,7 @@ module ActiveRecord
reflection = create_has_many_reflection(association_id, options, &extension)
configure_dependency_for_has_many(reflection)
add_association_callbacks(reflection.name, reflection.options)
if options[:through]
collection_accessor_methods(reflection, HasManyThroughAssociation)
else
collection_accessor_methods(reflection, HasManyAssociation)
end
collection_accessor_methods(reflection)
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1021,8 +1037,7 @@ module ActiveRecord
# [build_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+ and linked to this object through a foreign key, but has not
# yet been saved. <b>Note:</b> This ONLY works if an association already exists.
# It will NOT work if the association is +nil+.
# yet been saved.
# [create_association(attributes = {})]
# Returns a new object of the associated type that has been instantiated
# with +attributes+, linked to this object through a foreign key, and that
@@ -1115,14 +1130,12 @@ module ActiveRecord
def has_one(association_id, options = {})
if options[:through]
reflection = create_has_one_through_reflection(association_id, options)
association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation)
else
reflection = create_has_one_reflection(association_id, options)
association_accessor_methods(reflection, HasOneAssociation)
association_constructor_method(:build, reflection, HasOneAssociation)
association_constructor_method(:create, reflection, HasOneAssociation)
association_constructor_methods(reflection)
configure_dependency_for_has_one(reflection)
end
association_accessor_methods(reflection)
end
# Specifies a one-to-one association with another class. This method should only be used
@@ -1239,12 +1252,10 @@ module ActiveRecord
def belongs_to(association_id, options = {})
reflection = create_belongs_to_reflection(association_id, options)
if reflection.options[:polymorphic]
association_accessor_methods(reflection, BelongsToPolymorphicAssociation)
else
association_accessor_methods(reflection, BelongsToAssociation)
association_constructor_method(:build, reflection, BelongsToAssociation)
association_constructor_method(:create, reflection, BelongsToAssociation)
association_accessor_methods(reflection)
unless reflection.options[:polymorphic]
association_constructor_methods(reflection)
end
add_counter_cache_callbacks(reflection) if options[:counter_cache]
@@ -1429,7 +1440,7 @@ module ActiveRecord
# 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}'
def has_and_belongs_to_many(association_id, options = {}, &extension)
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
collection_accessor_methods(reflection)
# Don't use a before_destroy callback since users' before_destroy
# callbacks will be executed after the association is wiped out.
@@ -1461,15 +1472,10 @@ module ActiveRecord
table_name_prefix + join_table + table_name_suffix
end
def association_accessor_methods(reflection, association_proxy_class)
def association_accessor_methods(reflection)
redefine_method(reflection.name) do |*params|
force_reload = params.first unless params.empty?
association = association_instance_get(reflection.name)
if association.nil?
association = association_proxy_class.new(self, reflection)
association_instance_set(reflection.name, association)
end
association = association_proxy(reflection.name)
if force_reload
reflection.klass.uncached { association.reload }
@@ -1480,40 +1486,15 @@ module ActiveRecord
association.target.nil? ? nil : association
end
redefine_method("loaded_#{reflection.name}?") do
association = association_instance_get(reflection.name)
association && association.loaded?
end
redefine_method("#{reflection.name}=") do |record|
association = association_instance_get(reflection.name)
if association.nil?
association = association_proxy_class.new(self, reflection)
association_instance_set(reflection.name, association)
end
association.replace(record)
association.target.nil? ? nil : association
end
redefine_method("set_#{reflection.name}_target") do |target|
association = association_proxy_class.new(self, reflection)
association.target = target
association.loaded
association_instance_set(reflection.name, association)
association_proxy(reflection.name).replace(record)
end
end
def collection_reader_method(reflection, association_proxy_class)
def collection_reader_method(reflection)
redefine_method(reflection.name) do |*params|
force_reload = params.first unless params.empty?
association = association_instance_get(reflection.name)
unless association
association = association_proxy_class.new(self, reflection)
association_instance_set(reflection.name, association)
end
association = association_proxy(reflection.name)
if force_reload
reflection.klass.uncached { association.reload }
@@ -1533,15 +1514,12 @@ module ActiveRecord
end
end
def collection_accessor_methods(reflection, association_proxy_class, writer = true)
collection_reader_method(reflection, association_proxy_class)
def collection_accessor_methods(reflection, writer = true)
collection_reader_method(reflection)
if writer
redefine_method("#{reflection.name}=") do |new_value|
# Loads proxy class instance (defined in collection_reader_method) if not already loaded
association = send(reflection.name)
association.replace(new_value)
association
association_proxy(reflection.name).replace(new_value)
end
redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
@@ -1553,17 +1531,18 @@ module ActiveRecord
end
end
def association_constructor_method(constructor, reflection, association_proxy_class)
redefine_method("#{constructor}_#{reflection.name}") do |*params|
attributes = params.first unless params.empty?
association = association_instance_get(reflection.name)
def association_constructor_methods(reflection)
constructors = {
"build_#{reflection.name}" => "build",
"create_#{reflection.name}" => "create"
}
constructors["create_#{reflection.name}!"] = "create!" if reflection.macro == :has_one
unless association
association = association_proxy_class.new(self, reflection)
association_instance_set(reflection.name, association)
constructors.each do |name, proxy_name|
redefine_method(name) do |*params|
attributes = params.first unless params.empty?
association_proxy(reflection.name).send(proxy_name, attributes)
end
association.send(constructor, attributes)
end
end

View File

@@ -314,7 +314,11 @@ module ActiveRecord
transaction do
delete(@target - other_array)
concat(other_array - @target)
unless concat(other_array - @target)
raise RecordNotSaved, "Failed to replace #{@reflection.name} because one or more of the "
"new records could not be saved."
end
end
end

View File

@@ -213,7 +213,8 @@ module ActiveRecord
# Set the inverse association, if possible
def set_inverse_instance(record)
if record && invertible_for?(record)
record.send("set_#{inverse_reflection_for(record).name}_target", @owner)
inverse = record.send(:association_proxy, inverse_reflection_for(record).name)
inverse.target = @owner
end
end
@@ -259,23 +260,6 @@ module ActiveRecord
end
end
private
# Forwards any missing method call to the \target.
def method_missing(method, *args)
if load_target
unless @target.respond_to?(method)
message = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}"
raise NoMethodError, message
end
if block_given?
@target.send(method, *args) { |*block_args| yield(*block_args) }
else
@target.send(method, *args)
end
end
end
# Loads the \target if needed and returns it.
#
# This method is abstract in the sense that it relies on +find_target+,
@@ -299,6 +283,18 @@ module ActiveRecord
reset
end
private
# Forwards any missing method call to the \target.
def method_missing(method, *args, &block)
if load_target
return super unless @target.respond_to?(method)
@target.send(method, *args, &block)
end
rescue NoMethodError => e
raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@target}")
end
# Should be true if there is a foreign key present on the @owner which
# references the target. This is used to determine whether we can load
# the target if the @owner is currently a new record (and therefore

View File

@@ -223,7 +223,8 @@ module ActiveRecord
end
def set_target_and_inverse(join_part, association, record)
association_proxy = record.send("set_#{join_part.reflection.name}_target", association)
association_proxy = record.send(:association_proxy, join_part.reflection.name)
association_proxy.target = association
association_proxy.send(:set_inverse_instance, association)
end
end

View File

@@ -7,7 +7,7 @@ module ActiveRecord
end
def create!(attributes = {})
new_record(:create_association!, attributes)
build(attributes).tap { |record| record.save! }
end
def build(attributes = {})
@@ -19,23 +19,25 @@ module ActiveRecord
raise_on_type_mismatch(record) unless record.nil?
load_target
if @target && @target != record
remove_target(save && @reflection.options[:dependent])
end
@reflection.klass.transaction do
if @target && @target != record
remove_target!(@reflection.options[:dependent])
end
if record
set_owner_attributes(record)
set_inverse_instance(record)
if record
set_inverse_instance(record)
set_owner_attributes(record)
if @owner.persisted? && save && !record.save
nullify_owner_attributes(record)
set_owner_attributes(@target)
raise RecordNotSaved, "Failed to save the new associated #{@reflection.name}."
end
end
end
@target = record
loaded
if @owner.persisted? && record && save
record.save && self
else
record && self
end
end
private
@@ -49,21 +51,32 @@ module ActiveRecord
alias creation_attributes construct_owner_attributes
# The reason that the save param for replace is false, if for create (not just build),
# is because the setting of the foreign keys is actually handled by the scoping, and
# so they are set straight away and do not need to be updated within replace.
def new_record(method, attributes)
record = scoped.scoping { @reflection.send(method, attributes) }
replace(record, false)
record
end
def remove_target(method)
case method
when :delete, :destroy
def remove_target!(method)
if [:delete, :destroy].include?(method)
@target.send(method)
else
@target[@reflection.foreign_key] = nil
@target.save if @target.persisted? && @owner.persisted?
nullify_owner_attributes(@target)
if @target.persisted? && @owner.persisted? && !@target.save
set_owner_attributes(@target)
raise RecordNotSaved, "Failed to remove the existing associated #{@reflection.name}. " +
"The record failed to save when after its foreign key was set to nil."
end
end
end
def nullify_owner_attributes(record)
record[@reflection.foreign_key] = nil
end
end
end
end

View File

@@ -13,9 +13,8 @@ module ActiveRecord
private
def create_through_record(new_value)
proxy = @owner.send(@reflection.through_reflection.name) ||
@owner.send(:association_instance_get, @reflection.through_reflection.name)
record = proxy.target
proxy = @owner.send(:association_proxy, @reflection.through_reflection.name)
record = proxy.send(:load_target)
if record && !new_value
record.destroy
@@ -31,10 +30,6 @@ module ActiveRecord
end
end
end
def find_target
scoped.first
end
end
end
end

View File

@@ -880,6 +880,16 @@ module ActiveRecord #:nodoc:
record
end
# Finder methods must instantiate through this method to work with the
# single-table inheritance model that makes it possible to create
# objects of different types from the same table.
def instantiate(record) # :nodoc:
model = find_sti_class(record[inheritance_column]).allocate
model.init_with('attributes' => record)
model
end
private
def relation #:nodoc:
@@ -892,15 +902,6 @@ module ActiveRecord #:nodoc:
end
end
# Finder methods must instantiate through this method to work with the
# single-table inheritance model that makes it possible to create
# objects of different types from the same table.
def instantiate(record)
model = find_sti_class(record[inheritance_column]).allocate
model.init_with('attributes' => record)
model
end
def find_sti_class(type_name)
if type_name.blank? || !columns_hash.include?(inheritance_column)
self
@@ -1577,7 +1578,7 @@ MSG
# Returns true if the specified +attribute+ has been set by the user or by a database load and is neither
# nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
def attribute_present?(attribute)
!read_attribute(attribute).blank?
!_read_attribute(attribute).blank?
end
# Returns the column object for the named attribute.

View File

@@ -77,8 +77,8 @@ module ActiveRecord
false
end
# Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite
# does not.
# Does this adapter support savepoints? PostgreSQL and MySQL do,
# SQLite < 3.6.8 does not.
def supports_savepoints?
false
end

View File

@@ -62,6 +62,10 @@ module ActiveRecord
sqlite_version >= '2.0.0'
end
def supports_savepoints?
sqlite_version >= '3.6.8'
end
# Returns +true+ when the connection adapter supports prepared statement
# caching, otherwise returns +false+
def supports_statement_cache?
@@ -189,6 +193,18 @@ module ActiveRecord
exec_query(sql, name).rows
end
def create_savepoint
execute("SAVEPOINT #{current_savepoint_name}")
end
def rollback_to_savepoint
execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
end
def release_savepoint
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
end
def begin_db_transaction #:nodoc:
@connection.transaction
end

View File

@@ -313,6 +313,31 @@ module ActiveRecord
macro == :belongs_to
end
def proxy_class
case macro
when :belongs_to
if options[:polymorphic]
Associations::BelongsToPolymorphicAssociation
else
Associations::BelongsToAssociation
end
when :has_and_belongs_to_many
Associations::HasAndBelongsToManyAssociation
when :has_many
if options[:through]
Associations::HasManyThroughAssociation
else
Associations::HasManyAssociation
end
when :has_one
if options[:through]
Associations::HasOneThroughAssociation
else
Associations::HasOneAssociation
end
end
end
private
def derive_class_name
class_name = name.to_s.camelize

View File

@@ -282,15 +282,11 @@ module ActiveRecord
end
def type_cast_calculated_value(value, column, operation = nil)
if value.is_a?(String) || value.nil?
case operation
when 'count' then value.to_i
when 'sum' then type_cast_using_column(value || '0', column)
when 'average' then value.try(:to_d)
else type_cast_using_column(value, column)
end
else
type_cast_using_column(value, column)
case operation
when 'count' then value.to_i
when 'sum' then type_cast_using_column(value || '0', column)
when 'average' then value.try(:to_d)
else type_cast_using_column(value, column)
end
end

View File

@@ -83,7 +83,7 @@ HEADER
# first dump primary key column
if @connection.respond_to?(:pk_and_sequence_for)
pk, pk_seq = @connection.pk_and_sequence_for(table)
pk, _ = @connection.pk_and_sequence_for(table)
elsif @connection.respond_to?(:primary_key)
pk = @connection.primary_key(table)
end

View File

@@ -0,0 +1,52 @@
require "cases/helper"
module ActiveRecord
module Associations
class AsssociationProxyTest < ActiveRecord::TestCase
class FakeOwner
attr_accessor :new_record
alias :new_record? :new_record
def initialize
@new_record = false
end
end
class FakeReflection < Struct.new(:options, :klass)
def initialize options = {}, klass = nil
super
end
def check_validity!
true
end
end
class FakeTarget
end
class FakeTargetProxy < AssociationProxy
def association_scope
true
end
def find_target
FakeTarget.new
end
end
def test_method_missing_error
reflection = FakeReflection.new({}, Object.new)
owner = FakeOwner.new
proxy = FakeTargetProxy.new(owner, reflection)
exception = assert_raises(NoMethodError) do
proxy.omg
end
assert_match('omg', exception.message)
assert_match(FakeTarget.name, exception.message)
end
end
end
end

View File

@@ -146,6 +146,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
end
def test_with_polymorphic_and_condition
sponsor = Sponsor.create
member = Member.create :name => "Bert"
sponsor.sponsorable = member
assert_equal member, sponsor.sponsorable
assert_nil sponsor.sponsorable_with_conditions
end
def test_with_select
assert_equal Company.find(2).firm_with_select.attributes.size, 1
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1

View File

@@ -975,6 +975,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
assert !firm.clients.include?(:first_client)
end
def test_replace_failure
firm = companies(:first_firm)
account = Account.new
orig_accounts = firm.accounts.to_a
assert !account.valid?
assert !orig_accounts.empty?
assert_raise ActiveRecord::RecordNotSaved do
firm.accounts = [account]
end
assert_equal orig_accounts, firm.accounts
end
def test_get_ids
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
end

View File

@@ -2,9 +2,12 @@ require "cases/helper"
require 'models/developer'
require 'models/project'
require 'models/company'
require 'models/ship'
require 'models/pirate'
class HasOneAssociationsTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :developers_projects
self.use_transactional_fixtures = false unless supports_savepoints?
fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
def setup
Account.destroyed_account_ids.clear
@@ -91,18 +94,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
def test_nullification_on_association_change
firm = companies(:rails_core)
old_account_id = firm.account.id
firm.account = Account.new
firm.account = Account.new(:credit_limit => 5)
# account is dependent with nullify, therefore its firm_id should be nil
assert_nil Account.find(old_account_id).firm_id
end
def test_association_change_calls_delete
companies(:first_firm).deletable_account = Account.new
companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
end
def test_association_change_calls_destroy
companies(:first_firm).account = Account.new
companies(:first_firm).account = Account.new(:credit_limit => 5)
assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
end
@@ -164,21 +167,30 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal account, firm.account
end
def test_build_association_twice_without_saving_affects_nothing
count_of_account = Account.count
firm = Firm.find(:first)
firm.build_account("credit_limit" => 1000)
firm.build_account("credit_limit" => 2000)
assert_equal count_of_account, Account.count
end
def test_create_association
firm = Firm.create(:name => "GlobalMegaCorp")
account = firm.create_account(:credit_limit => 1000)
assert_equal account, firm.reload.account
end
def test_create_association_with_bang
firm = Firm.create(:name => "GlobalMegaCorp")
account = firm.create_account!(:credit_limit => 1000)
assert_equal account, firm.reload.account
end
def test_create_association_with_bang_failing
firm = Firm.create(:name => "GlobalMegaCorp")
assert_raise ActiveRecord::RecordInvalid do
firm.create_account!
end
account = firm.account
assert_not_nil account
account.credit_limit = 5
account.save
assert_equal account, firm.reload.account
end
def test_build
firm = Firm.new("name" => "GlobalMegaCorp")
firm.save
@@ -189,17 +201,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
assert_equal account, firm.account
end
def test_failing_build_association
firm = Firm.new("name" => "GlobalMegaCorp")
firm.save
firm.account = account = Account.new
assert_equal account, firm.account
assert !account.save
assert_equal account, firm.account
assert_equal ["can't be empty"], account.errors["credit_limit"]
end
def test_create
firm = Firm.new("name" => "GlobalMegaCorp")
firm.save
@@ -293,4 +294,51 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
new_account = companies(:first_firm).build_account(:firm_name => 'Account')
assert_equal new_account.firm_name, "Account"
end
def test_creation_failure_without_dependent_option
pirate = pirates(:blackbeard)
orig_ship = pirate.ship.target
assert_equal ships(:black_pearl), orig_ship
new_ship = pirate.create_ship
assert_not_equal ships(:black_pearl), new_ship
assert_equal new_ship, pirate.ship
assert new_ship.new_record?
assert_nil orig_ship.pirate_id
assert !orig_ship.changed? # check it was saved
end
def test_creation_failure_with_dependent_option
pirate = pirates(:blackbeard).becomes(DestructivePirate)
orig_ship = pirate.dependent_ship.target
new_ship = pirate.create_dependent_ship
assert new_ship.new_record?
assert orig_ship.destroyed?
end
def test_replacement_failure_due_to_existing_record_should_raise_error
pirate = pirates(:blackbeard)
pirate.ship.name = nil
assert !pirate.ship.valid?
assert_raise(ActiveRecord::RecordNotSaved) do
pirate.ship = ships(:interceptor)
end
assert_equal ships(:black_pearl), pirate.ship
assert_equal pirate.id, pirate.ship.pirate_id
end
def test_replacement_failure_due_to_new_record_should_raise_error
pirate = pirates(:blackbeard)
new_ship = Ship.new
assert_raise(ActiveRecord::RecordNotSaved) do
pirate.ship = new_ship
end
assert_equal ships(:black_pearl), pirate.ship
assert_equal pirate.id, pirate.ship.pirate_id
assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
assert_nil new_ship.pirate_id
end
end

View File

@@ -197,7 +197,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
MemberDetail.find(:all, :include => :member_type)
end
@new_detail = @member_details[0]
assert @new_detail.loaded_member_type?
assert @new_detail.send(:association_proxy, :member_type).loaded?
assert_not_nil assert_no_queries { @new_detail.member_type }
end

View File

@@ -13,7 +13,8 @@ require 'models/book'
require 'models/citation'
class AssociationsJoinModelTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
# Reload edges table from fixtures as otherwise repeated test was failing
:edges
@@ -522,7 +523,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
author = authors(:david)
author.stubs(:read_attribute).with('comments_count').returns(100)
author.stubs(:_read_attribute).with('comments_count').returns(100)
assert_equal 100, author.comments.size
assert !author.comments.loaded?
end

View File

@@ -90,7 +90,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm = Firm.find(:first)
assert firm.valid?
firm.account = Account.new
firm.build_account
assert !firm.account.valid?
assert !firm.valid?
@@ -102,7 +102,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
firm = Firm.find(:first)
assert firm.valid?
firm.unvalidated_account = Account.new
firm.build_unvalidated_account
assert !firm.unvalidated_account.valid?
assert firm.valid?
@@ -572,7 +572,7 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
end
class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -797,7 +797,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -917,7 +917,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@ship = Ship.create(:name => 'Nights Dirty Lightning')
@@ -1164,7 +1164,7 @@ module AutosaveAssociationOnACollectionAssociationTests
end
class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@association_name = :birds
@@ -1178,7 +1178,7 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
end
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@association_name = :parrots
@@ -1193,7 +1193,7 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T
end
class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1209,7 +1209,7 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
end
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1230,7 +1230,7 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes
end
class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1250,7 +1250,7 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::
end
class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
@@ -1272,7 +1272,7 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test
end
class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.new

View File

@@ -23,6 +23,11 @@ class CalculationsTest < ActiveRecord::TestCase
assert_equal 53.0, value
end
def test_should_return_decimal_average_of_integer_field
value = Account.average(:id)
assert_equal 3.5, value
end
def test_should_return_nil_as_average
assert_nil NumericData.average(:bank_balance)
end

View File

@@ -26,6 +26,15 @@ def current_adapter?(*types)
end
end
def in_memory_db?
current_adapter?(:SQLiteAdapter) &&
ActiveRecord::Base.connection_pool.spec.config[:database] == ":memory:"
end
def supports_savepoints?
ActiveRecord::Base.connection.supports_savepoints?
end
def with_env_tz(new_tz = 'US/Eastern')
old_tz, ENV['TZ'] = ENV['TZ'], new_tz
yield
@@ -100,11 +109,11 @@ class ActiveSupport::TestCase
end
end
# silence verbose schema loading
original_stdout = $stdout
$stdout = StringIO.new
def load_schema
# silence verbose schema loading
original_stdout = $stdout
$stdout = StringIO.new
begin
adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
@@ -117,6 +126,8 @@ ensure
$stdout = original_stdout
end
load_schema
class << Time
unless method_defined? :now_before_time_travel
alias_method :now_before_time_travel, :now
@@ -133,4 +144,3 @@ class << Time
@now = nil
end
end

View File

@@ -19,11 +19,6 @@ end
class OptimisticLockingTest < ActiveRecord::TestCase
fixtures :people, :legacy_things, :references
# need to disable transactional fixtures, because otherwise the sqlite3
# adapter (at least) chokes when we try and change the schema in the middle
# of a test (see test_increment_counter_*).
self.use_transactional_fixtures = false
def test_lock_existing
p1 = Person.find(1)
p2 = Person.find(1)
@@ -152,6 +147,33 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_equal "unchangeable name", p.first_name
end
def test_quote_table_name
ref = references(:michael_magician)
ref.favourite = !ref.favourite
assert ref.save
end
# Useful for partial updates, don't only update the lock_version if there
# is nothing else being updated.
def test_update_without_attributes_does_not_only_update_lock_version
assert_nothing_raised do
p1 = Person.create!(:first_name => 'anika')
lock_version = p1.lock_version
p1.save
p1.reload
assert_equal lock_version, p1.lock_version
end
end
end
class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
fixtures :people, :legacy_things, :references
# need to disable transactional fixtures, because otherwise the sqlite3
# adapter (at least) chokes when we try and change the schema in the middle
# of a test (see test_increment_counter_*).
self.use_transactional_fixtures = false
{ :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
define_method("test_increment_counter_updates_#{name}") do
counter_test model, 1 do |id|
@@ -198,24 +220,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase
assert_raises(ActiveRecord::RecordNotFound) { LegacyThing.find(t.id) }
end
def test_quote_table_name
ref = references(:michael_magician)
ref.favourite = !ref.favourite
assert ref.save
end
# Useful for partial updates, don't only update the lock_version if there
# is nothing else being updated.
def test_update_without_attributes_does_not_only_update_lock_version
assert_nothing_raised do
p1 = Person.create!(:first_name => 'anika')
lock_version = p1.lock_version
p1.save
p1.reload
assert_equal lock_version, p1.lock_version
end
end
private
def add_counter_column_to(model, col='test_count')
@@ -252,9 +256,9 @@ end
# TODO: The Sybase, and OpenBase adapters currently have no support for pessimistic locking
unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db?
class PessimisticLockingTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
fixtures :people, :readers
def setup

View File

@@ -14,7 +14,7 @@ if ActiveRecord::Base.connection.supports_migrations?
class Reminder < ActiveRecord::Base; end
class ActiveRecord::Migration
class <<self
class << self
attr_accessor :message_count
end
@@ -2083,4 +2083,3 @@ if ActiveRecord::Base.connection.supports_migrations?
end
end
end

View File

@@ -6,7 +6,7 @@ require 'models/bird'
require_dependency 'models/course'
class MultipleDbTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@courses = create_fixtures("courses") { Course.retrieve_connection }

View File

@@ -859,7 +859,7 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase
end
class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@pirate = Pirate.create!(:catchphrase => "My baby takes tha mornin' train!")
@@ -899,7 +899,7 @@ class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRe
end
class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@ship = Ship.create!(:name => "The good ship Dollypop")

View File

@@ -137,4 +137,4 @@ class PooledConnectionsTest < ActiveRecord::TestCase
def add_record(name)
ActiveRecord::Base.connection_pool.with_connection { Project.create! :name => name }
end
end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
end unless current_adapter?(:FrontBase) || in_memory_db?

View File

@@ -63,7 +63,7 @@ class QueryCacheTest < ActiveRecord::TestCase
# Oracle adapter returns count() as Fixnum or Float
if current_adapter?(:OracleAdapter)
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
elsif current_adapter?(:SQLite3Adapter) && SQLite3::Version::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
elsif current_adapter?(:SQLite3Adapter) && SQLite3::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
# Future versions of the sqlite3 adapter will return numeric
assert_instance_of Fixnum,
Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")

View File

@@ -5,7 +5,7 @@ require 'active_record/session_store'
module ActiveRecord
class SessionStore
class SessionTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints? && ActiveRecord::Base.connection.supports_ddl_transactions?
def setup
super

View File

@@ -4,7 +4,7 @@ class TestRecord < ActiveRecord::Base
end
class TestUnconnectedAdapter < ActiveRecord::TestCase
self.use_transactional_fixtures = false
self.use_transactional_fixtures = false unless supports_savepoints?
def setup
@underlying = ActiveRecord::Base.connection
@@ -14,6 +14,7 @@ class TestUnconnectedAdapter < ActiveRecord::TestCase
def teardown
@underlying = nil
ActiveRecord::Base.establish_connection(@specification)
load_schema if in_memory_db?
end
def test_connection_no_longer_established

View File

@@ -6,19 +6,6 @@ require 'models/warehouse_thing'
require 'models/guid'
require 'models/event'
# The following methods in Topic are used in test_conditional_validation_*
class Topic
has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
end
class UniqueReply < Reply
validates_uniqueness_of :content, :scope => 'parent_id'
end
class SillyUniqueReply < UniqueReply
end
class Wizard < ActiveRecord::Base
self.abstract_class = true

View File

@@ -1,18 +0,0 @@
print "Using native SQLite3\n"
require_dependency 'models/course'
require 'logger'
ActiveRecord::Base.logger = Logger.new("debug.log")
class SqliteError < StandardError
end
def make_connection(clazz, db_definitions_file)
clazz.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
File.read(SCHEMA_ROOT + "/#{db_definitions_file}").split(';').each do |command|
clazz.connection.execute(command) unless command.strip.empty?
end
end
make_connection(ActiveRecord::Base, 'sqlite.sql')
make_connection(Course, 'sqlite2.sql')
load(SCHEMA_ROOT + "/schema.rb")

View File

@@ -0,0 +1,19 @@
# This file connects to an in-memory SQLite3 database, which is a very fast way to run the tests.
# The downside is that disconnect from the database results in the database effectively being
# wiped. For this reason, pooled_connections_test.rb is disabled when using an in-memory database.
print "Using native SQLite3 (in memory)\n"
require_dependency 'models/course'
require 'logger'
ActiveRecord::Base.logger = Logger.new("debug.log")
class SqliteError < StandardError
end
def make_connection(clazz)
ActiveRecord::Base.configurations = { clazz.name => { :adapter => 'sqlite3', :database => ':memory:' } }
clazz.establish_connection(clazz.name)
end
make_connection(ActiveRecord::Base)
make_connection(Course)

View File

@@ -1,5 +1,6 @@
black_pearl:
name: "Black Pearl"
pirate: blackbeard
interceptor:
id: 2
name: "Interceptor"

View File

@@ -78,3 +78,7 @@ class Pirate < ActiveRecord::Base
ship_log << "#{callback}_#{record.class.name.downcase}_#{record.id || '<new>'}"
end
end
class DestructivePirate < Pirate
has_one :dependent_ship, :class_name => 'Ship', :foreign_key => :pirate_id, :dependent => :destroy
end

View File

@@ -10,6 +10,13 @@ class Reply < Topic
attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read, :parent_title
end
class UniqueReply < Reply
validates_uniqueness_of :content, :scope => 'parent_id'
end
class SillyUniqueReply < UniqueReply
end
class WrongReply < Reply
validate :errors_on_empty_content
validate :title_is_wrong_create, :on => :create

View File

@@ -2,4 +2,6 @@ class Sponsor < ActiveRecord::Base
belongs_to :sponsor_club, :class_name => "Club", :foreign_key => "club_id"
belongs_to :sponsorable, :polymorphic => true
belongs_to :thing, :polymorphic => true, :foreign_type => :sponsorable_type, :foreign_key => :sponsorable_id
belongs_to :sponsorable_with_conditions, :polymorphic => true,
:foreign_type => 'sponsorable_type', :foreign_key => 'sponsorable_id', :conditions => {:name => 'Ernie'}
end

View File

@@ -45,6 +45,10 @@ class Topic < ActiveRecord::Base
has_many :replies, :dependent => :destroy, :foreign_key => "parent_id"
has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title"
has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
serialize :content
before_create :default_written_on

View File

@@ -18,6 +18,10 @@ class BigDecimal
end
end
def to_d
self
end
DEFAULT_STRING_FORMAT = 'F'
def to_formatted_s(format = DEFAULT_STRING_FORMAT)
_original_to_s(format)

View File

@@ -1,5 +1,5 @@
require 'date'
require 'active_support/inflector'
require 'active_support/inflector/methods'
require 'active_support/core_ext/date/zones'
class Date

View File

@@ -1,4 +1,4 @@
require 'active_support/inflector'
require 'active_support/inflector/methods'
require 'active_support/core_ext/time/conversions'
require 'active_support/core_ext/date_time/calculations'
require 'active_support/values/time_zone'

View File

@@ -1,4 +1,4 @@
require 'active_support/inflector'
require 'active_support/inflector/methods'
require 'active_support/core_ext/time/publicize_conversion_methods'
require 'active_support/values/time_zone'

View File

@@ -1,4 +1,4 @@
require 'active_support/inflector'
require 'active_support/inflector/methods'
module ActiveSupport
module Deprecation

View File

@@ -1,10 +1,17 @@
require 'abstract_unit'
require 'bigdecimal'
require 'active_support/core_ext/big_decimal'
class BigDecimalTest < Test::Unit::TestCase
def test_to_yaml
assert_equal("--- 100000.30020320320000000000000000000000000000001\n", BigDecimal.new('100000.30020320320000000000000000000000000000001').to_yaml)
assert_equal("--- .Inf\n", BigDecimal.new('Infinity').to_yaml)
assert_equal("--- .NaN\n", BigDecimal.new('NaN').to_yaml)
assert_equal("--- .Inf\n", BigDecimal.new('Infinity').to_yaml)
assert_equal("--- .NaN\n", BigDecimal.new('NaN').to_yaml)
assert_equal("--- -.Inf\n", BigDecimal.new('-Infinity').to_yaml)
end
end
def test_to_d
bd = BigDecimal.new '10'
assert_equal bd, bd.to_d
end
end

View File

@@ -4,6 +4,7 @@ require 'bigdecimal'
require 'active_support/core_ext/string/access'
require 'active_support/ordered_hash'
require 'active_support/core_ext/object/conversions'
require 'active_support/inflections'
class HashExtTest < Test::Unit::TestCase
class IndifferentHash < HashWithIndifferentAccess

View File

@@ -1,5 +1,6 @@
# encoding: utf-8
require 'abstract_unit'
require 'active_support/core_ext/string/inflections'
require 'active_support/json'
class TestJSONEncoding < Test::Unit::TestCase

View File

@@ -35,7 +35,7 @@ cd "#{root_dir}/activesupport" do
puts "[CruiseControl] Building Active Support"
puts
build_results[:activesupport] = rake 'test'
# build_results[:activesupport_isolated] = rake 'test:isolated'
build_results[:activesupport_isolated] = rake 'test:isolated'
end
system "sudo rm -R #{root_dir}/railties/tmp"
@@ -51,7 +51,7 @@ cd "#{root_dir}/actionpack" do
puts "[CruiseControl] Building Action Pack"
puts
build_results[:actionpack] = rake 'test'
# build_results[:actionpack_isolated] = rake 'test:isolated'
build_results[:actionpack_isolated] = rake 'test:isolated'
end
cd "#{root_dir}/actionmailer" do
@@ -59,7 +59,7 @@ cd "#{root_dir}/actionmailer" do
puts "[CruiseControl] Building Action Mailer"
puts
build_results[:actionmailer] = rake 'test'
# build_results[:actionmailer_isolated] = rake 'test:isolated'
build_results[:actionmailer_isolated] = rake 'test:isolated'
end
cd "#{root_dir}/activemodel" do
@@ -67,7 +67,7 @@ cd "#{root_dir}/activemodel" do
puts "[CruiseControl] Building Active Model"
puts
build_results[:activemodel] = rake 'test'
# build_results[:activemodel_isolated] = rake 'test:isolated'
build_results[:activemodel_isolated] = rake 'test:isolated'
end
rm_f "#{root_dir}/activeresource/debug.log"
@@ -76,7 +76,7 @@ cd "#{root_dir}/activeresource" do
puts "[CruiseControl] Building Active Resource"
puts
build_results[:activeresource] = rake 'test'
# build_results[:activeresource_isolated] = rake 'test:isolated'
build_results[:activeresource_isolated] = rake 'test:isolated'
end
rm_f "#{root_dir}/activerecord/debug.log"
@@ -85,7 +85,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building Active Record with MySQL"
puts
build_results[:activerecord_mysql] = rake 'mysql:rebuild_databases', 'mysql:test'
# build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
end
cd "#{root_dir}/activerecord" do
@@ -93,7 +93,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building Active Record with MySQL2"
puts
build_results[:activerecord_mysql2] = rake 'mysql:rebuild_databases', 'mysql2:test'
# build_results[:activerecord_mysql2_isolated] = rake 'mysql:rebuild_databases', 'mysql2:isolated_test'
build_results[:activerecord_mysql2_isolated] = rake 'mysql:rebuild_databases', 'mysql2:isolated_test'
end
cd "#{root_dir}/activerecord" do
@@ -101,7 +101,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building Active Record with PostgreSQL"
puts
build_results[:activerecord_postgresql8] = rake 'postgresql:rebuild_databases', 'postgresql:test'
# build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
end
cd "#{root_dir}/activerecord" do
@@ -109,7 +109,7 @@ cd "#{root_dir}/activerecord" do
puts "[CruiseControl] Building Active Record with SQLite 3"
puts
build_results[:activerecord_sqlite3] = rake 'sqlite3:test'
# build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
end

View File

@@ -18,7 +18,7 @@ namespace :test do
Dir["test/#{dir}/*_test.rb"].each do |file|
next true if file.include?("fixtures")
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
system(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
sh(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
end
end
end

View File

@@ -294,7 +294,7 @@ YAML
boot_rails
expected = %W(
expected_locales = %W(
#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
#{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
@@ -304,11 +304,11 @@ YAML
#{app_path}/app/locales/en.yml
).map { |path| File.expand_path(path) }
actual = I18n.load_path.map { |path| File.expand_path(path) }.find_all do |p|
p =~ /^#{RAILS_FRAMEWORK_ROOT}/ || p =~ /^#{@plugin.path}/ || p =~ /^#{app_path}/
end
actual_locales = I18n.load_path.map { |path|
File.expand_path(path)
} & expected_locales # remove locales external to Rails
assert_equal expected, actual
assert_equal expected_locales, actual_locales
assert_equal "2", I18n.t(:foo)
assert_equal "1", I18n.t(:bar)