aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test')
-rw-r--r--activerecord/test/cases/adapters/mysql/schema_test.rb2
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_test.rb36
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb25
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb2
-rw-r--r--activerecord/test/cases/associations/eager_test.rb4
-rw-r--r--activerecord/test/cases/associations/has_many_through_associations_test.rb2
-rw-r--r--activerecord/test/cases/base_test.rb8
-rw-r--r--activerecord/test/cases/finder_test.rb23
-rw-r--r--activerecord/test/cases/fixtures_test.rb5
-rw-r--r--activerecord/test/cases/identity_map/middleware_test.rb71
-rw-r--r--activerecord/test/cases/identity_map_test.rb18
-rw-r--r--activerecord/test/cases/log_subscriber_test.rb12
-rw-r--r--activerecord/test/cases/mass_assignment_security_test.rb437
-rw-r--r--activerecord/test/cases/persistence_test.rb42
-rw-r--r--activerecord/test/cases/query_cache_test.rb64
-rw-r--r--activerecord/test/cases/relation_scoping_test.rb20
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb7
-rw-r--r--activerecord/test/cases/validations/uniqueness_validation_test.rb26
-rw-r--r--activerecord/test/models/developer.rb24
-rw-r--r--activerecord/test/models/loose_person.rb24
-rw-r--r--activerecord/test/models/person.rb42
-rw-r--r--activerecord/test/schema/postgresql_specific_schema.rb10
-rw-r--r--activerecord/test/schema/schema.rb2
23 files changed, 831 insertions, 75 deletions
diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb
index c6c1d1dad5..a2155d1dd1 100644
--- a/activerecord/test/cases/adapters/mysql/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql/schema_test.rb
@@ -31,6 +31,6 @@ module ActiveRecord
def test_table_exists_wrong_schema
assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist")
end
- end if current_adapter?(:MysqlAdapter)
+ end
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb
new file mode 100644
index 0000000000..858d1da2dd
--- /dev/null
+++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb
@@ -0,0 +1,36 @@
+require "cases/helper"
+require 'models/post'
+require 'models/comment'
+
+module ActiveRecord
+ module ConnectionAdapters
+ class Mysql2SchemaTest < ActiveRecord::TestCase
+ fixtures :posts
+
+ def setup
+ @connection = ActiveRecord::Base.connection
+ db = Post.connection_pool.spec.config[:database]
+ table = Post.table_name
+ @db_name = db
+
+ @omgpost = Class.new(Post) do
+ set_table_name "#{db}.#{table}"
+ def self.name; 'Post'; end
+ end
+ end
+
+ def test_schema
+ assert @omgpost.find(:first)
+ end
+
+ def test_table_exists?
+ name = @omgpost.table_name
+ assert @connection.table_exists?(name), "#{name} table should exist"
+ end
+
+ def test_table_exists_wrong_schema
+ assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist")
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index 5bb8fa2f93..ce08e4c6a7 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -3,6 +3,9 @@ require "cases/helper"
class PostgresqlArray < ActiveRecord::Base
end
+class PostgresqlTsvector < ActiveRecord::Base
+end
+
class PostgresqlMoney < ActiveRecord::Base
end
@@ -34,6 +37,9 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
@connection.execute("INSERT INTO postgresql_arrays (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )")
@first_array = PostgresqlArray.find(1)
+ @connection.execute("INSERT INTO postgresql_tsvectors (text_vector) VALUES (' ''text'' ''vector'' ')")
+ @first_tsvector = PostgresqlTsvector.find(1)
+
@connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('567.89'::money)")
@connection.execute("INSERT INTO postgresql_moneys (wealth) VALUES ('-567.89'::money)")
@first_money = PostgresqlMoney.find(1)
@@ -62,6 +68,10 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
assert_equal :string, @first_array.column_for_attribute(:nicknames).type
end
+ def test_data_type_of_tsvector_types
+ assert_equal :tsvector, @first_tsvector.column_for_attribute(:text_vector).type
+ end
+
def test_data_type_of_money_types
assert_equal :decimal, @first_money.column_for_attribute(:wealth).type
end
@@ -95,11 +105,26 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
assert_equal '{foo,bar,baz}', @first_array.nicknames
end
+ def test_tsvector_values
+ assert_equal "'text' 'vector'", @first_tsvector.text_vector
+ end
+
def test_money_values
assert_equal 567.89, @first_money.wealth
assert_equal(-567.89, @second_money.wealth)
end
+ def test_update_tsvector
+ new_text_vector = "'new' 'text' 'vector'"
+ assert @first_tsvector.text_vector = new_text_vector
+ assert @first_tsvector.save
+ assert @first_tsvector.reload
+ assert @first_tsvector.text_vector = new_text_vector
+ assert @first_tsvector.save
+ assert @first_tsvector.reload
+ assert_equal @first_tsvector.text_vector, new_text_vector
+ end
+
def test_number_values
assert_equal 123.456, @first_number.single
assert_equal 123456.789, @first_number.double
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 9006914508..ddcc36c841 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -580,7 +580,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
post = posts(:welcome)
comment = comments(:greetings)
- assert_difference 'post.reload.taggings_count', -1 do
+ assert_difference lambda { post.reload.taggings_count }, -1 do
assert_difference 'comment.reload.taggings_count', +1 do
tagging.taggable = comment
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index 9bc7910fc6..3e92a77830 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -170,10 +170,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_equal [comment], category.posts[0].comments
end
end
-
+
def test_associations_loaded_for_all_records
post = Post.create!(:title => 'foo', :body => "I like cars!")
- comment = SpecialComment.create!(:body => 'Come on!', :post => post)
+ SpecialComment.create!(:body => 'Come on!', :post => post)
first_category = Category.create! :name => 'First!', :posts => [post]
second_category = Category.create! :name => 'Second!', :posts => [post]
diff --git a/activerecord/test/cases/associations/has_many_through_associations_test.rb b/activerecord/test/cases/associations/has_many_through_associations_test.rb
index 70a4e06dbe..89117593fd 100644
--- a/activerecord/test/cases/associations/has_many_through_associations_test.rb
+++ b/activerecord/test/cases/associations/has_many_through_associations_test.rb
@@ -760,7 +760,7 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
def test_primary_key_option_on_source
post = posts(:welcome)
category = categories(:general)
- categorization = Categorization.create!(:post_id => post.id, :named_category_name => category.name)
+ Categorization.create!(:post_id => post.id, :named_category_name => category.name)
assert_equal [category], post.named_categories
assert_equal [category.name], post.named_category_ids # checks when target loaded
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 815ff7b825..5ee3b2d776 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -18,7 +18,7 @@ require 'models/comment'
require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
-require 'models/loose_person'
+require 'models/person'
require 'models/edge'
require 'models/joke'
require 'rexml/document'
@@ -489,6 +489,12 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal 'value2', weird.send('a$b')
end
+ def test_attributes_guard_protected_attributes_is_deprecated
+ attributes = { "title" => "An amazing title" }
+ topic = Topic.new
+ assert_deprecated { topic.send(:attributes=, attributes, false) }
+ end
+
def test_multiparameter_attributes_on_date
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" }
topic = Topic.find(1)
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 655437318f..be4ba18555 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -1045,6 +1045,29 @@ class FinderTest < ActiveRecord::TestCase
:order => ' author_addresses_authors.id DESC ', :limit => 3).size
end
+ def test_find_with_nil_inside_set_passed_for_one_attribute
+ client_of = Company.find(
+ :all,
+ :conditions => {
+ :client_of => [2, 1, nil],
+ :name => ['37signals', 'Summit', 'Microsoft'] },
+ :order => 'client_of DESC'
+ ).map { |x| x.client_of }
+
+ assert client_of.include?(nil)
+ assert_equal [2, 1].sort, client_of.compact.sort
+ end
+
+ def test_find_with_nil_inside_set_passed_for_attribute
+ client_of = Company.find(
+ :all,
+ :conditions => { :client_of => [nil] },
+ :order => 'client_of DESC'
+ ).map { |x| x.client_of }
+
+ assert_equal [], client_of.compact
+ end
+
def test_with_limiting_with_custom_select
posts = Post.find(:all, :include => :author, :select => ' posts.*, authors.id as "author_id"', :limit => 3, :order => 'posts.id')
assert_equal 3, posts.size
diff --git a/activerecord/test/cases/fixtures_test.rb b/activerecord/test/cases/fixtures_test.rb
index fa40fad56d..3e20155210 100644
--- a/activerecord/test/cases/fixtures_test.rb
+++ b/activerecord/test/cases/fixtures_test.rb
@@ -45,6 +45,11 @@ class FixturesTest < ActiveRecord::TestCase
end
end
+ def test_create_fixtures
+ Fixtures.create_fixtures(FIXTURES_ROOT, "parrots")
+ assert Parrot.find_by_name('Curious George'), 'George is in the database'
+ end
+
def test_multiple_clean_fixtures
fixtures_array = nil
assert_nothing_raised { fixtures_array = create_fixtures(*FIXTURES) }
diff --git a/activerecord/test/cases/identity_map/middleware_test.rb b/activerecord/test/cases/identity_map/middleware_test.rb
new file mode 100644
index 0000000000..60dcad4586
--- /dev/null
+++ b/activerecord/test/cases/identity_map/middleware_test.rb
@@ -0,0 +1,71 @@
+require "cases/helper"
+
+module ActiveRecord
+ module IdentityMap
+ class MiddlewareTest < ActiveRecord::TestCase
+ def setup
+ super
+ @enabled = IdentityMap.enabled
+ IdentityMap.enabled = false
+ end
+
+ def teardown
+ super
+ IdentityMap.enabled = @enabled
+ IdentityMap.clear
+ end
+
+ def test_delegates
+ called = false
+ mw = Middleware.new lambda { |env|
+ called = true
+ }
+ mw.call({})
+ assert called, 'middleware delegated'
+ end
+
+ def test_im_enabled_during_delegation
+ mw = Middleware.new lambda { |env|
+ assert IdentityMap.enabled?, 'identity map should be enabled'
+ }
+ mw.call({})
+ end
+
+ class Enum < Struct.new(:iter)
+ def each(&b)
+ iter.call(&b)
+ end
+ end
+
+ def test_im_enabled_during_body_each
+ mw = Middleware.new lambda { |env|
+ [200, {}, Enum.new(lambda { |&b|
+ assert IdentityMap.enabled?, 'identity map should be enabled'
+ b.call "hello"
+ })]
+ }
+ body = mw.call({}).last
+ body.each { |x| assert_equal 'hello', x }
+ end
+
+ def test_im_disabled_after_body_close
+ mw = Middleware.new lambda { |env| [200, {}, []] }
+ body = mw.call({}).last
+ assert IdentityMap.enabled?, 'identity map should be enabled'
+ body.close
+ assert !IdentityMap.enabled?, 'identity map should be disabled'
+ end
+
+ def test_im_cleared_after_body_close
+ mw = Middleware.new lambda { |env| [200, {}, []] }
+ body = mw.call({}).last
+
+ IdentityMap.repository['hello'] = 'world'
+ assert !IdentityMap.repository.empty?, 'repo should not be empty'
+
+ body.close
+ assert IdentityMap.repository.empty?, 'repo should be empty'
+ end
+ end
+ end
+end
diff --git a/activerecord/test/cases/identity_map_test.rb b/activerecord/test/cases/identity_map_test.rb
index 199e59657d..649715fbb5 100644
--- a/activerecord/test/cases/identity_map_test.rb
+++ b/activerecord/test/cases/identity_map_test.rb
@@ -1,4 +1,5 @@
require "cases/helper"
+
require 'models/developer'
require 'models/project'
require 'models/company'
@@ -137,8 +138,6 @@ class IdentityMapTest < ActiveRecord::TestCase
assert_equal(["name"], swistak.changed)
assert_equal({"name" => ["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes)
- s = Subscriber.find('swistak')
-
assert swistak.name_changed?
assert_equal("Swistak Sreberkowiec", swistak.name)
end
@@ -149,8 +148,6 @@ class IdentityMapTest < ActiveRecord::TestCase
Subscriber.update_all({:name => "Raczkowski Marcin"}, {:name => "Marcin Raczkowski"})
- s = Subscriber.find('swistak')
-
assert_equal({"name"=>["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes)
assert_equal("Swistak Sreberkowiec", swistak.name)
end
@@ -163,8 +160,6 @@ class IdentityMapTest < ActiveRecord::TestCase
Subscriber.update_all({:name => "Swistak Sreberkowiec"}, {:name => "Marcin Raczkowski"})
- s = Subscriber.find('swistak')
-
assert_equal("Swistak Sreberkowiec", swistak.name)
assert_equal({"name"=>["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes)
assert swistak.name_changed?
@@ -175,7 +170,7 @@ class IdentityMapTest < ActiveRecord::TestCase
pirate.birds.create!(:name => 'Posideons Killer')
pirate.birds.create!(:name => 'Killer bandita Dionne')
- posideons, killer = pirate.birds
+ posideons, _ = pirate.birds
pirate.reload
@@ -388,15 +383,6 @@ class IdentityMapTest < ActiveRecord::TestCase
assert_not_nil post.title
end
- def test_log
- log = StringIO.new
- ActiveRecord::Base.logger = Logger.new(log)
- ActiveRecord::Base.logger.level = Logger::DEBUG
- Post.find 1
- Post.find 1
- assert_match(/Post with ID = 1 loaded from Identity Map/, log.string)
- end
-
# Currently AR is not allowing changing primary key (see Persistence#update)
# So we ignore it. If this changes, this test needs to be uncommented.
# def test_updating_of_pkey
diff --git a/activerecord/test/cases/log_subscriber_test.rb b/activerecord/test/cases/log_subscriber_test.rb
index 5f55299065..c6c6079490 100644
--- a/activerecord/test/cases/log_subscriber_test.rb
+++ b/activerecord/test/cases/log_subscriber_test.rb
@@ -1,11 +1,14 @@
require "cases/helper"
require "models/developer"
+require "models/post"
require "active_support/log_subscriber/test_helper"
class LogSubscriberTest < ActiveRecord::TestCase
include ActiveSupport::LogSubscriber::TestHelper
include ActiveSupport::BufferedLogger::Severity
+ fixtures :posts
+
def setup
@old_logger = ActiveRecord::Base.logger
@using_identity_map = ActiveRecord::IdentityMap.enabled?
@@ -91,4 +94,13 @@ class LogSubscriberTest < ActiveRecord::TestCase
def test_initializes_runtime
Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join
end
+
+ def test_log
+ ActiveRecord::IdentityMap.use do
+ Post.find 1
+ Post.find 1
+ end
+ wait
+ assert_match(/From Identity Map/, @logger.logged(:debug).last)
+ end
end
diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb
index 025ec1d3fa..fbbae99e8b 100644
--- a/activerecord/test/cases/mass_assignment_security_test.rb
+++ b/activerecord/test/cases/mass_assignment_security_test.rb
@@ -3,8 +3,65 @@ require 'models/company'
require 'models/subscriber'
require 'models/keyboard'
require 'models/task'
+require 'models/person'
+
+
+module MassAssignmentTestHelpers
+ def setup
+ # another AR test modifies the columns which causes issues with create calls
+ TightPerson.reset_column_information
+ LoosePerson.reset_column_information
+ end
+
+ def attributes_hash
+ {
+ :id => 5,
+ :first_name => 'Josh',
+ :gender => 'm',
+ :comments => 'rides a sweet bike'
+ }
+ end
+
+ def assert_default_attributes(person, create = false)
+ unless create
+ assert_nil person.id
+ else
+ assert !!person.id
+ end
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_nil person.comments
+ end
+
+ def assert_admin_attributes(person, create = false)
+ unless create
+ assert_nil person.id
+ else
+ assert !!person.id
+ end
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'rides a sweet bike', person.comments
+ end
+
+ def assert_all_attributes(person)
+ assert_equal 5, person.id
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'rides a sweet bike', person.comments
+ end
+end
+
+module MassAssignmentRelationTestHelpers
+ def setup
+ super
+ @person = LoosePerson.create(attributes_hash)
+ end
+end
+
class MassAssignmentSecurityTest < ActiveRecord::TestCase
+ include MassAssignmentTestHelpers
def test_customized_primary_key_remains_protected
subscriber = Subscriber.new(:nick => 'webster123', :name => 'nice try')
@@ -30,6 +87,120 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase
end
end
+ def test_assign_attributes_uses_default_scope_when_no_scope_is_provided
+ p = LoosePerson.new
+ p.assign_attributes(attributes_hash)
+
+ assert_default_attributes(p)
+ end
+
+ def test_assign_attributes_skips_mass_assignment_security_protection_when_without_protection_is_used
+ p = LoosePerson.new
+ p.assign_attributes(attributes_hash, :without_protection => true)
+
+ assert_all_attributes(p)
+ end
+
+ def test_assign_attributes_with_default_scope_and_attr_protected_attributes
+ p = LoosePerson.new
+ p.assign_attributes(attributes_hash, :as => :default)
+
+ assert_default_attributes(p)
+ end
+
+ def test_assign_attributes_with_admin_scope_and_attr_protected_attributes
+ p = LoosePerson.new
+ p.assign_attributes(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p)
+ end
+
+ def test_assign_attributes_with_default_scope_and_attr_accessible_attributes
+ p = TightPerson.new
+ p.assign_attributes(attributes_hash, :as => :default)
+
+ assert_default_attributes(p)
+ end
+
+ def test_assign_attributes_with_admin_scope_and_attr_accessible_attributes
+ p = TightPerson.new
+ p.assign_attributes(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p)
+ end
+
+ def test_new_with_attr_accessible_attributes
+ p = TightPerson.new(attributes_hash)
+
+ assert_default_attributes(p)
+ end
+
+ def test_new_with_attr_protected_attributes
+ p = LoosePerson.new(attributes_hash)
+
+ assert_default_attributes(p)
+ end
+
+ def test_create_with_attr_accessible_attributes
+ p = TightPerson.create(attributes_hash)
+
+ assert_default_attributes(p, true)
+ end
+
+ def test_create_with_attr_protected_attributes
+ p = LoosePerson.create(attributes_hash)
+
+ assert_default_attributes(p, true)
+ end
+
+ def test_new_with_admin_scope_with_attr_accessible_attributes
+ p = TightPerson.new(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p)
+ end
+
+ def test_new_with_admin_scope_with_attr_protected_attributes
+ p = LoosePerson.new(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p)
+ end
+
+ def test_create_with_admin_scope_with_attr_accessible_attributes
+ p = TightPerson.create(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p, true)
+ end
+
+ def test_create_with_admin_scope_with_attr_protected_attributes
+ p = LoosePerson.create(attributes_hash, :as => :admin)
+
+ assert_admin_attributes(p, true)
+ end
+
+ def test_new_with_without_protection_with_attr_accessible_attributes
+ p = TightPerson.new(attributes_hash, :without_protection => true)
+
+ assert_all_attributes(p)
+ end
+
+ def test_new_with_without_protection_with_attr_protected_attributes
+ p = LoosePerson.new(attributes_hash, :without_protection => true)
+
+ assert_all_attributes(p)
+ end
+
+ def test_create_with_without_protection_with_attr_accessible_attributes
+ p = TightPerson.create(attributes_hash, :without_protection => true)
+
+ assert_all_attributes(p)
+ end
+
+ def test_create_with_without_protection_with_attr_protected_attributes
+ p = LoosePerson.create(attributes_hash, :without_protection => true)
+
+ assert_all_attributes(p)
+ end
+
def test_protection_against_class_attribute_writers
[:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names,
:default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method|
@@ -40,4 +211,268 @@ class MassAssignmentSecurityTest < ActiveRecord::TestCase
end
end
-end \ No newline at end of file
+end
+
+
+class MassAssignmentSecurityHasOneRelationsTest < ActiveRecord::TestCase
+ include MassAssignmentTestHelpers
+ include MassAssignmentRelationTestHelpers
+
+ # build
+
+ def test_has_one_build_with_attr_protected_attributes
+ best_friend = @person.build_best_friend(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_attr_accessible_attributes
+ best_friend = @person.build_best_friend(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.build_best_friend(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.build_best_friend(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_without_protection
+ best_friend = @person.build_best_friend(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create
+
+ def test_has_one_create_with_attr_protected_attributes
+ best_friend = @person.create_best_friend(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.create_best_friend(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_without_protection
+ best_friend = @person.create_best_friend(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create!
+
+ def test_has_one_create_with_bang_with_attr_protected_attributes
+ best_friend = @person.create_best_friend!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_without_protection
+ best_friend = @person.create_best_friend!(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+end
+
+
+class MassAssignmentSecurityBelongsToRelationsTest < ActiveRecord::TestCase
+ include MassAssignmentTestHelpers
+ include MassAssignmentRelationTestHelpers
+
+ # build
+
+ def test_has_one_build_with_attr_protected_attributes
+ best_friend = @person.build_best_friend_of(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_attr_accessible_attributes
+ best_friend = @person.build_best_friend_of(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.build_best_friend_of(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.build_best_friend_of(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_without_protection
+ best_friend = @person.build_best_friend_of(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create
+
+ def test_has_one_create_with_attr_protected_attributes
+ best_friend = @person.create_best_friend_of(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend_of(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.create_best_friend_of(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend_of(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_without_protection
+ best_friend = @person.create_best_friend_of(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create!
+
+ def test_has_one_create_with_bang_with_attr_protected_attributes
+ best_friend = @person.create_best_friend!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.create_best_friend!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_without_protection
+ best_friend = @person.create_best_friend!(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+end
+
+
+class MassAssignmentSecurityHasManyRelationsTest < ActiveRecord::TestCase
+ include MassAssignmentTestHelpers
+ include MassAssignmentRelationTestHelpers
+
+ # build
+
+ def test_has_one_build_with_attr_protected_attributes
+ best_friend = @person.best_friends.build(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_attr_accessible_attributes
+ best_friend = @person.best_friends.build(attributes_hash)
+ assert_default_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.best_friends.build(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.best_friends.build(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend)
+ end
+
+ def test_has_one_build_without_protection
+ best_friend = @person.best_friends.build(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create
+
+ def test_has_one_create_with_attr_protected_attributes
+ best_friend = @person.best_friends.create(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_attr_accessible_attributes
+ best_friend = @person.best_friends.create(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.best_friends.create(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.best_friends.create(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_without_protection
+ best_friend = @person.best_friends.create(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+ # create!
+
+ def test_has_one_create_with_bang_with_attr_protected_attributes
+ best_friend = @person.best_friends.create!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_attr_accessible_attributes
+ best_friend = @person.best_friends.create!(attributes_hash)
+ assert_default_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_protected_attributes
+ best_friend = @person.best_friends.create!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_with_admin_scope_with_attr_accessible_attributes
+ best_friend = @person.best_friends.create!(attributes_hash, :as => :admin)
+ assert_admin_attributes(best_friend, true)
+ end
+
+ def test_has_one_create_with_bang_without_protection
+ best_friend = @person.best_friends.create!(attributes_hash, :without_protection => true)
+ assert_all_attributes(best_friend)
+ end
+
+end
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index 9aa13f04cd..b066575af8 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -12,7 +12,7 @@ require 'models/minimalistic'
require 'models/warehouse_thing'
require 'models/parrot'
require 'models/minivan'
-require 'models/loose_person'
+require 'models/person'
require 'rexml/document'
require 'active_support/core_ext/exception'
@@ -491,6 +491,26 @@ class PersistencesTest < ActiveRecord::TestCase
assert_equal "The First Topic", topic.title
end
+ def test_update_attributes_as_admin
+ person = TightPerson.create({ "first_name" => 'Joshua' })
+ person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
+ person.reload
+
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'from NZ', person.comments
+ end
+
+ def test_update_attributes_without_protection
+ person = TightPerson.create({ "first_name" => 'Joshua' })
+ person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
+ person.reload
+
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'from NZ', person.comments
+ end
+
def test_update_attributes!
Reply.validates_presence_of(:title)
reply = Reply.find(2)
@@ -512,6 +532,26 @@ class PersistencesTest < ActiveRecord::TestCase
Reply.reset_callbacks(:validate)
end
+ def test_update_attributes_with_bang_as_admin
+ person = TightPerson.create({ "first_name" => 'Joshua' })
+ person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
+ person.reload
+
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'from NZ', person.comments
+ end
+
+ def test_update_attributestes_with_bang_without_protection
+ person = TightPerson.create({ "first_name" => 'Joshua' })
+ person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
+ person.reload
+
+ assert_equal 'Josh', person.first_name
+ assert_equal 'm', person.gender
+ assert_equal 'from NZ', person.comments
+ end
+
def test_destroyed_returns_boolean
developer = Developer.first
assert_equal false, developer.destroyed?
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 287f7e255b..a61180cfaf 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -10,6 +10,70 @@ class QueryCacheTest < ActiveRecord::TestCase
def setup
Task.connection.clear_query_cache
+ ActiveRecord::Base.connection.disable_query_cache!
+ end
+
+ def test_middleware_delegates
+ called = false
+ mw = ActiveRecord::QueryCache.new lambda { |env|
+ called = true
+ }
+ mw.call({})
+ assert called, 'middleware should delegate'
+ end
+
+ def test_middleware_caches
+ mw = ActiveRecord::QueryCache.new lambda { |env|
+ Task.find 1
+ Task.find 1
+ assert_equal 1, ActiveRecord::Base.connection.query_cache.length
+ }
+ mw.call({})
+ end
+
+ def test_cache_enabled_during_call
+ assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache off'
+
+ mw = ActiveRecord::QueryCache.new lambda { |env|
+ assert ActiveRecord::Base.connection.query_cache_enabled, 'cache on'
+ }
+ mw.call({})
+ end
+
+ def test_cache_on_during_body_write
+ streaming = Class.new do
+ def each
+ yield ActiveRecord::Base.connection.query_cache_enabled
+ end
+ end
+
+ mw = ActiveRecord::QueryCache.new lambda { |env|
+ [200, {}, streaming.new]
+ }
+ body = mw.call({}).last
+ body.each { |x| assert x, 'cache should be on' }
+ body.close
+ assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache disabled'
+ end
+
+ def test_cache_off_after_close
+ mw = ActiveRecord::QueryCache.new lambda { |env| }
+ body = mw.call({}).last
+
+ assert ActiveRecord::Base.connection.query_cache_enabled, 'cache enabled'
+ body.close
+ assert !ActiveRecord::Base.connection.query_cache_enabled, 'cache disabled'
+ end
+
+ def test_cache_clear_after_close
+ mw = ActiveRecord::QueryCache.new lambda { |env|
+ Post.find(:first)
+ }
+ body = mw.call({}).last
+
+ assert !ActiveRecord::Base.connection.query_cache.empty?, 'cache not empty'
+ body.close
+ assert ActiveRecord::Base.connection.query_cache.empty?, 'cache should be empty'
end
def test_find_queries
diff --git a/activerecord/test/cases/relation_scoping_test.rb b/activerecord/test/cases/relation_scoping_test.rb
index 2ed676fe69..864b3d4846 100644
--- a/activerecord/test/cases/relation_scoping_test.rb
+++ b/activerecord/test/cases/relation_scoping_test.rb
@@ -355,6 +355,12 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert_equal 50000, wheres[:salary]
end
+ def test_default_scope_with_module_includes
+ wheres = ModuleIncludedPoorDeveloperCalledJamis.scoped.where_values_hash
+ assert_equal "Jamis", wheres[:name]
+ assert_equal 50000, wheres[:salary]
+ end
+
def test_default_scope_with_multiple_calls
wheres = MultiplePoorDeveloperCalledJamis.scoped.where_values_hash
assert_equal "Jamis", wheres[:name]
@@ -456,18 +462,4 @@ class DefaultScopingTest < ActiveRecord::TestCase
assert DeveloperCalledJamis.unscoped.poor.include?(developers(:david).becomes(DeveloperCalledJamis))
assert_equal 10, DeveloperCalledJamis.unscoped.poor.length
end
-
- def test_multiple_default_scope_calls_are_deprecated
- klass = Class.new(ActiveRecord::Base)
-
- assert_not_deprecated do
- klass.send(:default_scope, :foo => :bar)
- end
-
- assert_deprecated do
- klass.send(:default_scope, :foo => :bar)
- end
-
- assert_equal 2, klass.default_scopes.length
- end
end
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index 9b2c7c00df..e8f2f44189 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -203,6 +203,13 @@ class SchemaDumperTest < ActiveRecord::TestCase
assert_match %r{t.xml "data"}, output
end
end
+
+ def test_schema_dump_includes_tsvector_shorthand_definition
+ output = standard_dump
+ if %r{create_table "postgresql_tsvectors"} =~ output
+ assert_match %r{t.tsvector "text_vector"}, output
+ end
+ end
end
def test_schema_dump_keeps_large_precision_integer_columns_as_decimal
diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb
index b4f3dd034c..0f1b3667cc 100644
--- a/activerecord/test/cases/validations/uniqueness_validation_test.rb
+++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb
@@ -162,6 +162,32 @@ class UniquenessValidationTest < ActiveRecord::TestCase
end
end
+ def test_validate_case_sensitive_uniqueness_with_special_sql_like_chars
+ Topic.validates_uniqueness_of(:title, :case_sensitive => true)
+
+ t = Topic.new("title" => "I'm unique!")
+ assert t.save, "Should save t as unique"
+
+ t2 = Topic.new("title" => "I'm %")
+ assert t2.save, "Should save t2 as unique"
+
+ t3 = Topic.new("title" => "I'm uniqu_!")
+ assert t3.save, "Should save t3 as unique"
+ end
+
+ def test_validate_case_insensitive_uniqueness_with_special_sql_like_chars
+ Topic.validates_uniqueness_of(:title, :case_sensitive => false)
+
+ t = Topic.new("title" => "I'm unique!")
+ assert t.save, "Should save t as unique"
+
+ t2 = Topic.new("title" => "I'm %")
+ assert t2.save, "Should save t2 as unique"
+
+ t3 = Topic.new("title" => "I'm uniqu_!")
+ assert t3.save, "Should save t3 as unique"
+ end
+
def test_validate_case_sensitive_uniqueness
Topic.validates_uniqueness_of(:title, :case_sensitive => true, :allow_nil => true)
diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb
index 10701dd6fd..152f804e16 100644
--- a/activerecord/test/models/developer.rb
+++ b/activerecord/test/models/developer.rb
@@ -129,28 +129,40 @@ end
class DeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis')
scope :poor, where('salary < 150000')
end
class PoorDeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis', :salary => 50000)
end
class InheritedPoorDeveloperCalledJamis < DeveloperCalledJamis
self.table_name = 'developers'
- ActiveSupport::Deprecation.silence do
- default_scope where(:salary => 50000)
- end
+ default_scope where(:salary => 50000)
end
class MultiplePoorDeveloperCalledJamis < ActiveRecord::Base
self.table_name = 'developers'
+
default_scope where(:name => 'Jamis')
+ default_scope where(:salary => 50000)
+end
- ActiveSupport::Deprecation.silence do
- default_scope where(:salary => 50000)
- end
+module SalaryDefaultScope
+ extend ActiveSupport::Concern
+
+ included { default_scope where(:salary => 50000) }
end
+
+class ModuleIncludedPoorDeveloperCalledJamis < DeveloperCalledJamis
+ self.table_name = 'developers'
+
+ include SalaryDefaultScope
+end
+
+
diff --git a/activerecord/test/models/loose_person.rb b/activerecord/test/models/loose_person.rb
deleted file mode 100644
index 256c281d0d..0000000000
--- a/activerecord/test/models/loose_person.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class LoosePerson < ActiveRecord::Base
- self.table_name = 'people'
- self.abstract_class = true
-
- attr_protected :credit_rating, :administrator
-end
-
-class LooseDescendant < LoosePerson
- attr_protected :phone_number
-end
-
-class LooseDescendantSecond< LoosePerson
- attr_protected :phone_number
- attr_protected :name
-end
-
-class TightPerson < ActiveRecord::Base
- self.table_name = 'people'
- attr_accessible :name, :address
-end
-
-class TightDescendant < TightPerson
- attr_accessible :phone_number
-end \ No newline at end of file
diff --git a/activerecord/test/models/person.rb b/activerecord/test/models/person.rb
index ad59d12672..a58c9bf572 100644
--- a/activerecord/test/models/person.rb
+++ b/activerecord/test/models/person.rb
@@ -1,6 +1,6 @@
class Person < ActiveRecord::Base
has_many :readers
- has_one :reader
+ has_one :reader
has_many :posts, :through => :readers
has_many :posts_with_no_comments, :through => :readers, :source => :post, :include => :comments, :conditions => 'comments.id is null'
@@ -8,23 +8,23 @@ class Person < ActiveRecord::Base
has_many :references
has_many :bad_references
has_many :fixed_bad_references, :conditions => { :favourite => true }, :class_name => 'BadReference'
- has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
+ has_one :favourite_reference, :class_name => 'Reference', :conditions => ['favourite=?', true]
has_many :posts_with_comments_sorted_by_comment_id, :through => :readers, :source => :post, :include => :comments, :order => 'comments.id'
has_many :jobs, :through => :references
- has_many :jobs_with_dependent_destroy, :source => :job, :through => :references, :dependent => :destroy
+ has_many :jobs_with_dependent_destroy, :source => :job, :through => :references, :dependent => :destroy
has_many :jobs_with_dependent_delete_all, :source => :job, :through => :references, :dependent => :delete_all
- has_many :jobs_with_dependent_nullify, :source => :job, :through => :references, :dependent => :nullify
+ has_many :jobs_with_dependent_nullify, :source => :job, :through => :references, :dependent => :nullify
belongs_to :primary_contact, :class_name => 'Person'
has_many :agents, :class_name => 'Person', :foreign_key => 'primary_contact_id'
has_many :agents_of_agents, :through => :agents, :source => :agents
belongs_to :number1_fan, :class_name => 'Person'
- has_many :agents_posts, :through => :agents, :source => :posts
+ has_many :agents_posts, :through => :agents, :source => :posts
has_many :agents_posts_authors, :through => :agents_posts, :source => :author
- scope :males, :conditions => { :gender => 'M' }
+ scope :males, :conditions => { :gender => 'M' }
scope :females, :conditions => { :gender => 'F' }
end
@@ -48,3 +48,33 @@ class PersonWithDependentNullifyJobs < ActiveRecord::Base
has_many :references, :foreign_key => :person_id
has_many :jobs, :source => :job, :through => :references, :dependent => :nullify
end
+
+
+class LoosePerson < ActiveRecord::Base
+ self.table_name = 'people'
+ self.abstract_class = true
+
+ attr_protected :comments
+ attr_protected :as => :admin
+
+ has_one :best_friend, :class_name => 'LoosePerson', :foreign_key => :best_friend_id
+ belongs_to :best_friend_of, :class_name => 'LoosePerson', :foreign_key => :best_friend_of_id
+
+ has_many :best_friends, :class_name => 'LoosePerson', :foreign_key => :best_friend_id
+end
+
+class LooseDescendant < LoosePerson; end
+
+class TightPerson < ActiveRecord::Base
+ self.table_name = 'people'
+
+ attr_accessible :first_name, :gender
+ attr_accessible :first_name, :gender, :comments, :as => :admin
+
+ has_one :best_friend, :class_name => 'TightPerson', :foreign_key => :best_friend_id
+ belongs_to :best_friend_of, :class_name => 'TightPerson', :foreign_key => :best_friend_of_id
+
+ has_many :best_friends, :class_name => 'TightPerson', :foreign_key => :best_friend_id
+end
+
+class TightDescendant < TightPerson; end \ No newline at end of file
diff --git a/activerecord/test/schema/postgresql_specific_schema.rb b/activerecord/test/schema/postgresql_specific_schema.rb
index f38f4f3b44..5cf9a207f3 100644
--- a/activerecord/test/schema/postgresql_specific_schema.rb
+++ b/activerecord/test/schema/postgresql_specific_schema.rb
@@ -1,6 +1,6 @@
ActiveRecord::Schema.define do
- %w(postgresql_arrays postgresql_moneys postgresql_numbers postgresql_times postgresql_network_addresses postgresql_bit_strings
+ %w(postgresql_tsvectors postgresql_arrays postgresql_moneys postgresql_numbers postgresql_times postgresql_network_addresses postgresql_bit_strings
postgresql_oids postgresql_xml_data_type defaults geometrics postgresql_timestamp_with_zones).each do |table_name|
execute "DROP TABLE IF EXISTS #{quote_table_name table_name}"
end
@@ -55,6 +55,14 @@ _SQL
nicknames TEXT[]
);
_SQL
+
+ execute <<_SQL
+ CREATE TABLE postgresql_tsvectors (
+ id SERIAL PRIMARY KEY,
+ text_vector tsvector
+ );
+_SQL
+
execute <<_SQL
CREATE TABLE postgresql_moneys (
id SERIAL PRIMARY KEY,
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index ceadb05644..9479242e4f 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -438,6 +438,8 @@ ActiveRecord::Schema.define do
t.references :number1_fan
t.integer :lock_version, :null => false, :default => 0
t.string :comments
+ t.references :best_friend
+ t.references :best_friend_of
t.timestamps
end