diff options
Diffstat (limited to 'activerecord/test/cases/adapters')
13 files changed, 258 insertions, 26 deletions
diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb index 7fe2c02c04..475a292f85 100644 --- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb +++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb @@ -46,6 +46,46 @@ module ActiveRecord assert_equal str, value end + def test_tables_quoting + begin + @conn.tables(nil, "foo-bar", nil) + flunk + rescue => e + # assertion for *quoted* database properly + assert_match(/database 'foo-bar'/, e.inspect) + end + end + + def test_pk_and_sequence_for + pk, seq = @conn.pk_and_sequence_for('ex') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex', 'id'), seq + end + + def test_pk_and_sequence_for_with_non_standard_primary_key + @conn.exec_query('drop table if exists ex_with_non_standard_pk') + @conn.exec_query(<<-eosql) + CREATE TABLE `ex_with_non_standard_pk` ( + `code` INT(11) DEFAULT NULL auto_increment, + PRIMARY KEY (`code`)) + eosql + pk, seq = @conn.pk_and_sequence_for('ex_with_non_standard_pk') + assert_equal 'code', pk + assert_equal @conn.default_sequence_name('ex_with_non_standard_pk', 'code'), seq + end + + def test_pk_and_sequence_for_with_custom_index_type_pk + @conn.exec_query('drop table if exists ex_with_custom_index_type_pk') + @conn.exec_query(<<-eosql) + CREATE TABLE `ex_with_custom_index_type_pk` ( + `id` INT(11) DEFAULT NULL auto_increment, + PRIMARY KEY USING BTREE (`id`)) + eosql + pk, seq = @conn.pk_and_sequence_for('ex_with_custom_index_type_pk') + assert_equal 'id', pk + assert_equal @conn.default_sequence_name('ex_with_custom_index_type_pk', 'id'), seq + end + private def insert(ctx, data) binds = data.map { |name, value| diff --git a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb index 292c7efebb..6faceaf7c0 100644 --- a/activerecord/test/cases/adapters/mysql/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql/reserved_word_test.rb @@ -130,7 +130,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase end def test_associations_work_with_reserved_words - assert_nothing_raised { Select.find(:all, :include => [:groups]) } + assert_nothing_raised { Select.scoped(:includes => [:groups]).all } end #the following functions were added to DRY test cases diff --git a/activerecord/test/cases/adapters/mysql/schema_test.rb b/activerecord/test/cases/adapters/mysql/schema_test.rb index 29f885c6e7..d94bb629a7 100644 --- a/activerecord/test/cases/adapters/mysql/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql/schema_test.rb @@ -20,7 +20,7 @@ module ActiveRecord end def test_schema - assert @omgpost.find(:first) + assert @omgpost.first end def test_primary_key diff --git a/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb b/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb index cd9c1041dc..5e8065d80d 100644 --- a/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb +++ b/activerecord/test/cases/adapters/mysql2/bind_parameter_test.rb @@ -9,7 +9,7 @@ module ActiveRecord def test_update_question_marks str = "foo?bar" - x = Topic.find :first + x = Topic.first x.title = str x.content = str x.save! @@ -28,7 +28,7 @@ module ActiveRecord def test_update_null_bytes str = "foo\0bar" - x = Topic.find :first + x = Topic.first x.title = str x.content = str x.save! diff --git a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb index 3a9744e78f..32d4282623 100644 --- a/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb +++ b/activerecord/test/cases/adapters/mysql2/reserved_word_test.rb @@ -130,7 +130,7 @@ class MysqlReservedWordTest < ActiveRecord::TestCase end def test_associations_work_with_reserved_words - assert_nothing_raised { Select.find(:all, :include => [:groups]) } + assert_nothing_raised { Select.scoped(:includes => [:groups]).all } end #the following functions were added to DRY test cases diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb index d5676bc522..2c0ed73c92 100644 --- a/activerecord/test/cases/adapters/mysql2/schema_test.rb +++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb @@ -20,7 +20,7 @@ module ActiveRecord end def test_schema - assert @omgpost.find(:first) + assert @omgpost.first end def test_primary_key @@ -35,6 +35,17 @@ module ActiveRecord def test_table_exists_wrong_schema assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist") end + + def test_tables_quoting + begin + @connection.tables(nil, "foo-bar", nil) + flunk + rescue => e + # assertion for *quoted* database properly + assert_match(/database 'foo-bar'/, e.inspect) + end + end + end end end diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb index e4746d4aa3..447d729e52 100644 --- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb @@ -21,6 +21,18 @@ class PostgresqlActiveSchemaTest < ActiveRecord::TestCase assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1) end + def test_add_index + # add_index calls index_name_exists? which can't work since execute is stubbed + ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) do |*| + false + end + + expected = %(CREATE UNIQUE INDEX "index_people_on_last_name" ON "people" ("last_name") WHERE state = 'active') + assert_equal expected, add_index(:people, :last_name, :unique => true, :where => "state = 'active'") + + ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:remove_method, :index_name_exists?) + end + private def method_missing(method_symbol, *arguments) ActiveRecord::Base.connection.send(method_symbol, *arguments) diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb index 0b61f61572..619d581d5f 100644 --- a/activerecord/test/cases/adapters/postgresql/explain_test.rb +++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb @@ -22,6 +22,13 @@ module ActiveRecord assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" IN (1)), explain assert_match %(Seq Scan on audit_logs), explain end + + def test_dont_explain_for_set_search_path + queries = Thread.current[:available_queries_for_explain] = [] + ActiveRecord::Base.connection.schema_search_path = "public" + assert queries.empty? + end + end end end diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb index 33bf4478cc..23bafde17b 100644 --- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb +++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb @@ -1,4 +1,8 @@ +# encoding: utf-8 + require "cases/helper" +require 'active_record/base' +require 'active_record/connection_adapters/postgresql_adapter' class PostgresqlHstoreTest < ActiveRecord::TestCase class Hstore < ActiveRecord::Base @@ -10,12 +14,13 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase begin @connection.transaction do @connection.create_table('hstores') do |t| - t.hstore 'tags' + t.hstore 'tags', :default => '' end end rescue ActiveRecord::StatementInvalid return skip "do not test on PG without hstore" end + @column = Hstore.columns.find { |c| c.name == 'tags' } end def teardown @@ -23,30 +28,83 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase end def test_column - column = Hstore.columns.find { |c| c.name == 'tags' } - assert column - assert_equal :hstore, column.type + assert_equal :hstore, @column.type end def test_type_cast_hstore - column = Hstore.columns.find { |c| c.name == 'tags' } - assert column + assert @column data = "\"1\"=>\"2\"" - hash = column.class.cast_hstore data + hash = @column.class.string_to_hstore data assert_equal({'1' => '2'}, hash) - assert_equal({'1' => '2'}, column.type_cast(data)) + assert_equal({'1' => '2'}, @column.type_cast(data)) + + assert_equal({}, @column.type_cast("")) + assert_equal({'key'=>nil}, @column.type_cast('key => NULL')) + assert_equal({'c'=>'}','"a"'=>'b "a b'}, @column.type_cast(%q(c=>"}", "\"a\""=>"b \"a b"))) + end + + def test_gen1 + assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''})) + end + + def test_gen2 + assert_equal(%q(","=>""), @column.class.hstore_to_string({','=>''})) + end + + def test_gen3 + assert_equal(%q("="=>""), @column.class.hstore_to_string({'='=>''})) + end + + def test_gen4 + assert_equal(%q(">"=>""), @column.class.hstore_to_string({'>'=>''})) + end + + def test_parse1 + assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @column.type_cast('a=>null,b=>NuLl,c=>"NuLl",null=>c')) + end + + def test_parse2 + assert_equal({" " => " "}, @column.type_cast("\\ =>\\ ")) + end + + def test_parse3 + assert_equal({"=" => ">"}, @column.type_cast("==>>")) end + def test_parse4 + assert_equal({"=a"=>"q=w"}, @column.type_cast('\=a=>q=w')) + end + + def test_parse5 + assert_equal({"=a"=>"q=w"}, @column.type_cast('"=a"=>q\=w')) + end + + def test_parse6 + assert_equal({"\"a"=>"q>w"}, @column.type_cast('"\"a"=>q>w')) + end + + def test_parse7 + assert_equal({"\"a"=>"q\"w"}, @column.type_cast('\"a=>q"w')) + end + + def test_rewrite + @connection.execute "insert into hstores (tags) VALUES ('1=>2')" + x = Hstore.first + x.tags = { '"a\'' => 'b' } + assert x.save! + end + + def test_select @connection.execute "insert into hstores (tags) VALUES ('1=>2')" - x = Hstore.find :first + x = Hstore.first assert_equal({'1' => '2'}, x.tags) end def test_select_multikey @connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')" - x = Hstore.find :first + x = Hstore.first assert_equal({'1' => '2', '2' => '3'}, x.tags) end @@ -54,6 +112,10 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase assert_cycle('a' => 'b', '1' => '2') end + def test_nil + assert_cycle('a' => nil) + end + def test_quotes assert_cycle('a' => 'b"ar', '1"foo' => '2') end @@ -74,13 +136,19 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase assert_cycle('a=>b' => 'bar', '1"foo' => '2') end + def test_quoting_special_characters + assert_cycle('ca' => 'cà', 'ac' => 'àc') + end + private def assert_cycle hash + # test creation x = Hstore.create!(:tags => hash) x.reload assert_equal(hash, x.tags) - # make sure updates work + # test updating + x = Hstore.create!(:tags => {}) x.tags = hash x.save! x.reload diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb index d57794daf8..92e31a3e44 100644 --- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -49,6 +49,33 @@ module ActiveRecord assert_equal expect, id end + def test_insert_sql_with_returning_disabled + connection = connection_without_insert_returning + id = connection.insert_sql("insert into postgresql_partitioned_table_parent (number) VALUES (1)") + expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + assert_equal expect, id + end + + def test_exec_insert_with_returning_disabled + connection = connection_without_insert_returning + result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id', 'postgresql_partitioned_table_parent_id_seq') + expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + assert_equal expect, result.rows.first.first + end + + def test_exec_insert_with_returning_disabled_and_no_sequence_name_given + connection = connection_without_insert_returning + result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id') + expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first + assert_equal expect, result.rows.first.first + end + + def test_sql_for_insert_with_returning_disabled + connection = connection_without_insert_returning + result = connection.sql_for_insert('sql', nil, nil, nil, 'binds') + assert_equal ['sql', 'binds'], result + end + def test_serial_sequence assert_equal 'public.accounts_id_seq', @connection.serial_sequence('accounts', 'id') @@ -179,6 +206,17 @@ module ActiveRecord assert_equal Arel.sql('$2'), bind end + def test_partial_index + @connection.add_index 'ex', %w{ id number }, :name => 'partial', :where => "number > 100" + index = @connection.indexes('ex').find { |idx| idx.name == 'partial' } + assert_equal "(number > 100)", index.where + end + + def test_distinct_with_nulls + assert_equal "DISTINCT posts.title, posts.updater_id AS alias_0", @connection.distinct("posts.title", ["posts.updater_id desc nulls first"]) + assert_equal "DISTINCT posts.title, posts.updater_id AS alias_0", @connection.distinct("posts.title", ["posts.updater_id desc nulls last"]) + end + private def insert(ctx, data) binds = data.map { |name, value| @@ -193,6 +231,10 @@ module ActiveRecord ctx.exec_insert(sql, 'SQL', binds) end + + def connection_without_insert_returning + ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false)) + end end end end diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb index 18670b4177..9208f53997 100644 --- a/activerecord/test/cases/adapters/postgresql/schema_test.rb +++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb @@ -24,6 +24,8 @@ class SchemaTest < ActiveRecord::TestCase 'moment timestamp without time zone default now()' ] PK_TABLE_NAME = 'table_with_pk' + UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq' + UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk' class Thing1 < ActiveRecord::Base self.table_name = "test_schema.things" @@ -60,6 +62,8 @@ class SchemaTest < ActiveRecord::TestCase @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);" @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);" @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)" + @connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}" + @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))" end def teardown @@ -67,6 +71,45 @@ class SchemaTest < ActiveRecord::TestCase @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE" end + def test_schema_names + assert_equal ["public", "test_schema", "test_schema2"], @connection.schema_names + end + + def test_create_schema + begin + @connection.create_schema "test_schema3" + assert @connection.schema_names.include? "test_schema3" + ensure + @connection.drop_schema "test_schema3" + end + end + + def test_raise_create_schema_with_existing_schema + begin + @connection.create_schema "test_schema3" + assert_raises(ActiveRecord::StatementInvalid) do + @connection.create_schema "test_schema3" + end + ensure + @connection.drop_schema "test_schema3" + end + end + + def test_drop_schema + begin + @connection.create_schema "test_schema3" + ensure + @connection.drop_schema "test_schema3" + end + assert !@connection.schema_names.include?("test_schema3") + end + + def test_raise_drop_schema_with_nonexisting_schema + assert_raises(ActiveRecord::StatementInvalid) do + @connection.drop_schema "test_schema3" + end + end + def test_schema_change_with_prepared_stmt altered = false @connection.exec_query "select * from developers where id = $1", 'sql', [[nil, 1]] @@ -179,13 +222,13 @@ class SchemaTest < ActiveRecord::TestCase end def test_raise_on_unquoted_schema_name - assert_raise(ActiveRecord::StatementInvalid) do + assert_raises(ActiveRecord::StatementInvalid) do with_schema_search_path '$user,public' end end def test_without_schema_search_path - assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) } + assert_raises(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) } end def test_ignore_nil_schema_search_path @@ -241,12 +284,12 @@ class SchemaTest < ActiveRecord::TestCase def test_pk_and_sequence_for_with_schema_specified [ %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}"), - %(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"), - %(#{SCHEMA_NAME}.#{PK_TABLE_NAME}) + %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}") ].each do |given| pk, seq = @connection.pk_and_sequence_for(given) assert_equal 'id', pk, "primary key should be found when table referenced as #{given}" - assert_equal "#{SCHEMA_NAME}.#{PK_TABLE_NAME}_id_seq", seq, "sequence name should be found when table referenced as #{given}" + assert_equal "#{PK_TABLE_NAME}_id_seq", seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}") + assert_equal "#{UNMATCHED_SEQUENCE_NAME}", seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}") end end diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb index e0152e7ccf..2ba9143cd5 100644 --- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb @@ -1,10 +1,11 @@ require "cases/helper" require 'bigdecimal' require 'yaml' +require 'securerandom' module ActiveRecord module ConnectionAdapters - class SQLiteAdapter + class SQLite3Adapter class QuotingTest < ActiveRecord::TestCase def setup @conn = Base.sqlite3_connection :database => ':memory:', @@ -12,6 +13,14 @@ module ActiveRecord :timeout => 100 end + def test_type_cast_binary_encoding_without_logger + @conn.extend(Module.new { def logger; end }) + column = Struct.new(:type, :name).new(:string, "foo") + binary = SecureRandom.hex + expected = binary.dup.encode!('utf-8') + assert_equal expected, @conn.type_cast(binary, column) + end + def test_type_cast_symbol assert_equal 'foo', @conn.type_cast(:foo, nil) end @@ -70,9 +79,9 @@ module ActiveRecord assert_equal bd.to_f, @conn.type_cast(bd, nil) end - def test_type_cast_unknown + def test_type_cast_unknown_should_raise_error obj = Class.new.new - assert_equal YAML.dump(obj), @conn.type_cast(obj, nil) + assert_raise(TypeError) { @conn.type_cast(obj, nil) } end def test_quoted_id diff --git a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb index ae272e2c4b..2f04c60a9a 100644 --- a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb +++ b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb @@ -1,7 +1,7 @@ require 'cases/helper' module ActiveRecord::ConnectionAdapters - class SQLiteAdapter + class SQLite3Adapter class StatementPoolTest < ActiveRecord::TestCase def test_cache_is_per_pid return skip('must support fork') unless Process.respond_to?(:fork) |