提交 bd09afb5 编写于 作者: R Rafael Mendonça França

Don't skip tests if we don't need to.

We can conditional define the tests depending on the adapter or
connection.

Lets keep the skip for fail tests that need to be fixed.
上级 3d5e83fe
......@@ -195,22 +195,20 @@ def teardown
Klass.remove_connection
end
test "transaction state is reset after a reconnect" do
skip "in-memory db doesn't allow reconnect" if in_memory_db?
@connection.begin_transaction
assert @connection.transaction_open?
@connection.reconnect!
assert !@connection.transaction_open?
end
test "transaction state is reset after a disconnect" do
skip "in-memory db doesn't allow disconnect" if in_memory_db?
unless in_memory_db?
test "transaction state is reset after a reconnect" do
@connection.begin_transaction
assert @connection.transaction_open?
@connection.reconnect!
assert !@connection.transaction_open?
end
@connection.begin_transaction
assert @connection.transaction_open?
@connection.disconnect!
assert !@connection.transaction_open?
test "transaction state is reset after a disconnect" do
@connection.begin_transaction
assert @connection.transaction_open?
@connection.disconnect!
assert !@connection.transaction_open?
end
end
end
end
......@@ -16,15 +16,15 @@ def test_mysql_reconnect_attribute_after_connection_with_reconnect_true
end
end
def test_connect_with_url
run_without_connection do
ar_config = ARTest.connection_config['arunit']
skip "This test doesn't work with custom socket location" if ar_config['socket']
url = "mysql://#{ar_config["username"]}@localhost/#{ar_config["database"]}"
Klass.establish_connection(url)
assert_equal ar_config['database'], Klass.connection.current_database
unless ARTest.connection_config['arunit']['socket']
def test_connect_with_url
run_without_connection do
ar_config = ARTest.connection_config['arunit']
url = "mysql://#{ar_config["username"]}@localhost/#{ar_config["database"]}"
Klass.establish_connection(url)
assert_equal ar_config['database'], Klass.connection.current_database
end
end
end
......
......@@ -3,20 +3,20 @@
module ActiveRecord::ConnectionAdapters
class MysqlAdapter
class StatementPoolTest < ActiveRecord::TestCase
def test_cache_is_per_pid
return skip('must support fork') unless Process.respond_to?(:fork)
if Process.respond_to?(:fork)
def test_cache_is_per_pid
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
end
end
end
end
......
......@@ -98,33 +98,33 @@ def test_statement_key_is_logged
# you know the incantation to do that.
# To restart PostgreSQL 9.1 on OS X, installed via MacPorts, ...
# sudo su postgres -c "pg_ctl restart -D /opt/local/var/db/postgresql91/defaultdb/ -m fast"
def test_reconnection_after_actual_disconnection_with_verify
skip "with_manual_interventions is false in configuration" unless ARTest.config['with_manual_interventions']
if ARTest.config['with_manual_interventions']
def test_reconnection_after_actual_disconnection_with_verify
original_connection_pid = @connection.query('select pg_backend_pid()')
original_connection_pid = @connection.query('select pg_backend_pid()')
# Sanity check.
assert @connection.active?
# Sanity check.
assert @connection.active?
puts 'Kill the connection now (e.g. by restarting the PostgreSQL ' +
'server with the "-m fast" option) and then press enter.'
$stdin.gets
puts 'Kill the connection now (e.g. by restarting the PostgreSQL ' +
'server with the "-m fast" option) and then press enter.'
$stdin.gets
@connection.verify!
@connection.verify!
assert @connection.active?
assert @connection.active?
# If we get no exception here, then either we re-connected successfully, or
# we never actually got disconnected.
new_connection_pid = @connection.query('select pg_backend_pid()')
# If we get no exception here, then either we re-connected successfully, or
# we never actually got disconnected.
new_connection_pid = @connection.query('select pg_backend_pid()')
assert_not_equal original_connection_pid, new_connection_pid,
"umm -- looks like you didn't break the connection, because we're still " +
"successfully querying with the same connection pid."
assert_not_equal original_connection_pid, new_connection_pid,
"umm -- looks like you didn't break the connection, because we're still " +
"successfully querying with the same connection pid."
# Repair all fixture connections so other tests won't break.
@fixture_connections.each do |c|
c.verify!
# Repair all fixture connections so other tests won't break.
@fixture_connections.each do |c|
c.verify!
end
end
end
......
......@@ -184,16 +184,6 @@ def test_data_type_of_array_types
assert_equal :text, @first_array.column_for_attribute(:nicknames).type
end
def test_data_type_of_range_types
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal :daterange, @first_range.column_for_attribute(:date_range).type
assert_equal :numrange, @first_range.column_for_attribute(:num_range).type
assert_equal :tsrange, @first_range.column_for_attribute(:ts_range).type
assert_equal :tstzrange, @first_range.column_for_attribute(:tstz_range).type
assert_equal :int4range, @first_range.column_for_attribute(:int4_range).type
assert_equal :int8range, @first_range.column_for_attribute(:int8_range).type
end
def test_data_type_of_tsvector_types
assert_equal :tsvector, @first_tsvector.column_for_attribute(:text_vector).type
end
......@@ -240,57 +230,185 @@ def test_tsvector_values
assert_equal "'text' 'vector'", @first_tsvector.text_vector
end
def test_int4range_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal 1...11, @first_range.int4_range
assert_equal 2...10, @second_range.int4_range
assert_equal 2...Float::INFINITY, @third_range.int4_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int4_range)
assert_nil @empty_range.int4_range
end
if ActiveRecord::Base.connection.supports_ranges?
def test_data_type_of_range_types
assert_equal :daterange, @first_range.column_for_attribute(:date_range).type
assert_equal :numrange, @first_range.column_for_attribute(:num_range).type
assert_equal :tsrange, @first_range.column_for_attribute(:ts_range).type
assert_equal :tstzrange, @first_range.column_for_attribute(:tstz_range).type
assert_equal :int4range, @first_range.column_for_attribute(:int4_range).type
assert_equal :int8range, @first_range.column_for_attribute(:int8_range).type
end
def test_int8range_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal 10...101, @first_range.int8_range
assert_equal 11...100, @second_range.int8_range
assert_equal 11...Float::INFINITY, @third_range.int8_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int8_range)
assert_nil @empty_range.int8_range
end
def test_int4range_values
assert_equal 1...11, @first_range.int4_range
assert_equal 2...10, @second_range.int4_range
assert_equal 2...Float::INFINITY, @third_range.int4_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int4_range)
assert_nil @empty_range.int4_range
end
def test_daterange_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 5), @first_range.date_range
assert_equal Date.new(2012, 1, 3)...Date.new(2012, 1, 4), @second_range.date_range
assert_equal Date.new(2012, 1, 3)...Float::INFINITY, @third_range.date_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.date_range)
assert_nil @empty_range.date_range
end
def test_int8range_values
assert_equal 10...101, @first_range.int8_range
assert_equal 11...100, @second_range.int8_range
assert_equal 11...Float::INFINITY, @third_range.int8_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.int8_range)
assert_nil @empty_range.int8_range
end
def test_numrange_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal BigDecimal.new('0.1')..BigDecimal.new('0.2'), @first_range.num_range
assert_equal BigDecimal.new('0.1')...BigDecimal.new('0.2'), @second_range.num_range
assert_equal BigDecimal.new('0.1')...BigDecimal.new('Infinity'), @third_range.num_range
assert_equal BigDecimal.new('-Infinity')...BigDecimal.new('Infinity'), @fourth_range.num_range
assert_nil @empty_range.num_range
end
def test_daterange_values
assert_equal Date.new(2012, 1, 2)...Date.new(2012, 1, 5), @first_range.date_range
assert_equal Date.new(2012, 1, 3)...Date.new(2012, 1, 4), @second_range.date_range
assert_equal Date.new(2012, 1, 3)...Float::INFINITY, @third_range.date_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.date_range)
assert_nil @empty_range.date_range
end
def test_tsrange_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tz = ::ActiveRecord::Base.default_timezone
assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)..Time.send(tz, 2011, 1, 1, 14, 30, 0), @first_range.ts_range
assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 1, 1, 14, 30, 0), @second_range.ts_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.ts_range)
assert_nil @empty_range.ts_range
end
def test_numrange_values
assert_equal BigDecimal.new('0.1')..BigDecimal.new('0.2'), @first_range.num_range
assert_equal BigDecimal.new('0.1')...BigDecimal.new('0.2'), @second_range.num_range
assert_equal BigDecimal.new('0.1')...BigDecimal.new('Infinity'), @third_range.num_range
assert_equal BigDecimal.new('-Infinity')...BigDecimal.new('Infinity'), @fourth_range.num_range
assert_nil @empty_range.num_range
end
def test_tsrange_values
tz = ::ActiveRecord::Base.default_timezone
assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)..Time.send(tz, 2011, 1, 1, 14, 30, 0), @first_range.ts_range
assert_equal Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 1, 1, 14, 30, 0), @second_range.ts_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.ts_range)
assert_nil @empty_range.ts_range
end
def test_tstzrange_values
assert_equal Time.parse('2010-01-01 09:30:00 UTC')..Time.parse('2011-01-01 17:30:00 UTC'), @first_range.tstz_range
assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Time.parse('2011-01-01 17:30:00 UTC'), @second_range.tstz_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
assert_nil @empty_range.tstz_range
end
def test_tstzrange_values
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
assert_equal Time.parse('2010-01-01 09:30:00 UTC')..Time.parse('2011-01-01 17:30:00 UTC'), @first_range.tstz_range
assert_equal Time.parse('2010-01-01 09:30:00 UTC')...Time.parse('2011-01-01 17:30:00 UTC'), @second_range.tstz_range
assert_equal(-Float::INFINITY...Float::INFINITY, @fourth_range.tstz_range)
assert_nil @empty_range.tstz_range
def test_create_tstzrange
tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')
range = PostgresqlRange.new(:tstz_range => tstzrange)
assert range.save
assert range.reload
assert_equal range.tstz_range, tstzrange
assert_equal range.tstz_range, Time.parse('2010-01-01 13:30:00 UTC')...Time.parse('2011-02-02 19:30:00 UTC')
end
def test_update_tstzrange
new_tstzrange = Time.parse('2010-01-01 14:30:00 CDT')...Time.parse('2011-02-02 14:30:00 CET')
@first_range.tstz_range = new_tstzrange
assert @first_range.save
assert @first_range.reload
assert_equal new_tstzrange, @first_range.tstz_range
@first_range.tstz_range = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2010-01-01 13:30:00 +0000')
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.tstz_range
end
def test_create_tsrange
tz = ::ActiveRecord::Base.default_timezone
tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
range = PostgresqlRange.new(:ts_range => tsrange)
assert range.save
assert range.reload
assert_equal range.ts_range, tsrange
end
def test_update_tsrange
tz = ::ActiveRecord::Base.default_timezone
new_tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
@first_range.ts_range = new_tsrange
assert @first_range.save
assert @first_range.reload
assert_equal new_tsrange, @first_range.ts_range
@first_range.ts_range = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2010, 1, 1, 14, 30, 0)
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.ts_range
end
def test_create_numrange
numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
range = PostgresqlRange.new(:num_range => numrange)
assert range.save
assert range.reload
assert_equal range.num_range, numrange
end
def test_update_numrange
new_numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
@first_range.num_range = new_numrange
assert @first_range.save
assert @first_range.reload
assert_equal new_numrange, @first_range.num_range
@first_range.num_range = BigDecimal.new('0.5')...BigDecimal.new('0.5')
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.num_range
end
def test_create_daterange
daterange = Range.new(Date.new(2012, 1, 1), Date.new(2013, 1, 1), true)
range = PostgresqlRange.new(:date_range => daterange)
assert range.save
assert range.reload
assert_equal range.date_range, daterange
end
def test_update_daterange
new_daterange = Date.new(2012, 2, 3)...Date.new(2012, 2, 10)
@first_range.date_range = new_daterange
assert @first_range.save
assert @first_range.reload
assert_equal new_daterange, @first_range.date_range
@first_range.date_range = Date.new(2012, 2, 3)...Date.new(2012, 2, 3)
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.date_range
end
def test_create_int4range
int4range = Range.new(3, 50, true)
range = PostgresqlRange.new(:int4_range => int4range)
assert range.save
assert range.reload
assert_equal range.int4_range, int4range
end
def test_update_int4range
new_int4range = 6...10
@first_range.int4_range = new_int4range
assert @first_range.save
assert @first_range.reload
assert_equal new_int4range, @first_range.int4_range
@first_range.int4_range = 3...3
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.int4_range
end
def test_create_int8range
int8range = Range.new(30, 50, true)
range = PostgresqlRange.new(:int8_range => int8range)
assert range.save
assert range.reload
assert_equal range.int8_range, int8range
end
def test_update_int8range
new_int8range = 60000...10000000
@first_range.int8_range = new_int8range
assert @first_range.save
assert @first_range.reload
assert_equal new_int8range, @first_range.int8_range
@first_range.int8_range = 39999...39999
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.int8_range
end
end
def test_money_values
......@@ -306,141 +424,6 @@ def test_money_type_cast
assert_equal(-2.25, column.type_cast("($2.25)"))
end
def test_create_tstzrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tstzrange = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2011-02-02 14:30:00 CDT')
range = PostgresqlRange.new(:tstz_range => tstzrange)
assert range.save
assert range.reload
assert_equal range.tstz_range, tstzrange
assert_equal range.tstz_range, Time.parse('2010-01-01 13:30:00 UTC')...Time.parse('2011-02-02 19:30:00 UTC')
end
def test_update_tstzrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
new_tstzrange = Time.parse('2010-01-01 14:30:00 CDT')...Time.parse('2011-02-02 14:30:00 CET')
@first_range.tstz_range = new_tstzrange
assert @first_range.save
assert @first_range.reload
assert_equal new_tstzrange, @first_range.tstz_range
@first_range.tstz_range = Time.parse('2010-01-01 14:30:00 +0100')...Time.parse('2010-01-01 13:30:00 +0000')
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.tstz_range
end
def test_create_tsrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tz = ::ActiveRecord::Base.default_timezone
tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
range = PostgresqlRange.new(:ts_range => tsrange)
assert range.save
assert range.reload
assert_equal range.ts_range, tsrange
end
def test_update_tsrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
tz = ::ActiveRecord::Base.default_timezone
new_tsrange = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2011, 2, 2, 14, 30, 0)
@first_range.ts_range = new_tsrange
assert @first_range.save
assert @first_range.reload
assert_equal new_tsrange, @first_range.ts_range
@first_range.ts_range = Time.send(tz, 2010, 1, 1, 14, 30, 0)...Time.send(tz, 2010, 1, 1, 14, 30, 0)
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.ts_range
end
def test_create_numrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
range = PostgresqlRange.new(:num_range => numrange)
assert range.save
assert range.reload
assert_equal range.num_range, numrange
end
def test_update_numrange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
new_numrange = BigDecimal.new('0.5')...BigDecimal.new('1')
@first_range.num_range = new_numrange
assert @first_range.save
assert @first_range.reload
assert_equal new_numrange, @first_range.num_range
@first_range.num_range = BigDecimal.new('0.5')...BigDecimal.new('0.5')
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.num_range
end
def test_create_daterange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
daterange = Range.new(Date.new(2012, 1, 1), Date.new(2013, 1, 1), true)
range = PostgresqlRange.new(:date_range => daterange)
assert range.save
assert range.reload
assert_equal range.date_range, daterange
end
def test_update_daterange
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
new_daterange = Date.new(2012, 2, 3)...Date.new(2012, 2, 10)
@first_range.date_range = new_daterange
assert @first_range.save
assert @first_range.reload
assert_equal new_daterange, @first_range.date_range
@first_range.date_range = Date.new(2012, 2, 3)...Date.new(2012, 2, 3)
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.date_range
end
def test_create_int4range
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
int4range = Range.new(3, 50, true)
range = PostgresqlRange.new(:int4_range => int4range)
assert range.save
assert range.reload
assert_equal range.int4_range, int4range
end
def test_update_int4range
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
new_int4range = 6...10
@first_range.int4_range = new_int4range
assert @first_range.save
assert @first_range.reload
assert_equal new_int4range, @first_range.int4_range
@first_range.int4_range = 3...3
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.int4_range
end
def test_create_int8range
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
int8range = Range.new(30, 50, true)
range = PostgresqlRange.new(:int8_range => int8range)
assert range.save
assert range.reload
assert_equal range.int8_range, int8range
end
def test_update_int8range
skip "PostgreSQL 9.2 required for range datatypes" unless @connection.supports_ranges?
new_int8range = 60000...10000000
@first_range.int8_range = new_int8range
assert @first_range.save
assert @first_range.reload
assert_equal new_int8range, @first_range.int8_range
@first_range.int8_range = 39999...39999
assert @first_range.save
assert @first_range.reload
assert_nil @first_range.int8_range
end
def test_update_tsvector
new_text_vector = "'new' 'text' 'vector'"
@first_tsvector.text_vector = new_text_vector
......
......@@ -14,10 +14,6 @@ class Hstore < ActiveRecord::Base
def setup
@connection = ActiveRecord::Base.connection
unless @connection.supports_extensions?
return skip "do not test on PG without hstore"
end
unless @connection.extension_enabled?('hstore')
@connection.enable_extension 'hstore'
@connection.commit_db_transaction
......@@ -38,191 +34,193 @@ def teardown
@connection.execute 'drop table if exists hstores'
end
def test_hstore_included_in_extensions
assert @connection.respond_to?(:extensions), "connection should have a list of extensions"
assert @connection.extensions.include?('hstore'), "extension list should include hstore"
end
if ActiveRecord::Base.connection.supports_extensions?
def test_hstore_included_in_extensions
assert @connection.respond_to?(:extensions), "connection should have a list of extensions"
assert @connection.extensions.include?('hstore'), "extension list should include hstore"
end
def test_disable_enable_hstore
assert @connection.extension_enabled?('hstore')
@connection.disable_extension 'hstore'
assert_not @connection.extension_enabled?('hstore')
@connection.enable_extension 'hstore'
assert @connection.extension_enabled?('hstore')
ensure
# Restore column(s) dropped by `drop extension hstore cascade;`
load_schema
end
def test_disable_enable_hstore
assert @connection.extension_enabled?('hstore')
@connection.disable_extension 'hstore'
assert_not @connection.extension_enabled?('hstore')
@connection.enable_extension 'hstore'
assert @connection.extension_enabled?('hstore')
ensure
# Restore column(s) dropped by `drop extension hstore cascade;`
load_schema
end
def test_column
assert_equal :hstore, @column.type
end
def test_column
assert_equal :hstore, @column.type
end
def test_change_table_supports_hstore
@connection.transaction do
@connection.change_table('hstores') do |t|
t.hstore 'users', default: ''
def test_change_table_supports_hstore
@connection.transaction do
@connection.change_table('hstores') do |t|
t.hstore 'users', default: ''
end
Hstore.reset_column_information
column = Hstore.columns.find { |c| c.name == 'users' }
assert_equal :hstore, column.type
raise ActiveRecord::Rollback # reset the schema change
end
ensure
Hstore.reset_column_information
column = Hstore.columns.find { |c| c.name == 'users' }
assert_equal :hstore, column.type
raise ActiveRecord::Rollback # reset the schema change
end
ensure
Hstore.reset_column_information
end
def test_cast_value_on_write
x = Hstore.new tags: {"bool" => true, "number" => 5}
assert_equal({"bool" => "true", "number" => "5"}, x.tags)
x.save
assert_equal({"bool" => "true", "number" => "5"}, x.reload.tags)
end
def test_type_cast_hstore
assert @column
def test_cast_value_on_write
x = Hstore.new tags: {"bool" => true, "number" => 5}
assert_equal({"bool" => "true", "number" => "5"}, x.tags)
x.save
assert_equal({"bool" => "true", "number" => "5"}, x.reload.tags)
end
data = "\"1\"=>\"2\""
hash = @column.class.string_to_hstore data
assert_equal({'1' => '2'}, hash)
assert_equal({'1' => '2'}, @column.type_cast(data))
def test_type_cast_hstore
assert @column
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
data = "\"1\"=>\"2\""
hash = @column.class.string_to_hstore data
assert_equal({'1' => '2'}, hash)
assert_equal({'1' => '2'}, @column.type_cast(data))
def test_with_store_accessors
x = Hstore.new(language: "fr", timezone: "GMT")
assert_equal "fr", x.language
assert_equal "GMT", x.timezone
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
x.save!
x = Hstore.first
assert_equal "fr", x.language
assert_equal "GMT", x.timezone
def test_with_store_accessors
x = Hstore.new(language: "fr", timezone: "GMT")
assert_equal "fr", x.language
assert_equal "GMT", x.timezone
x.language = "de"
x.save!
x.save!
x = Hstore.first
assert_equal "fr", x.language
assert_equal "GMT", x.timezone
x = Hstore.first
assert_equal "de", x.language
assert_equal "GMT", x.timezone
end
x.language = "de"
x.save!
def test_gen1
assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''}))
end
x = Hstore.first
assert_equal "de", x.language
assert_equal "GMT", x.timezone
end
def test_gen2
assert_equal(%q(","=>""), @column.class.hstore_to_string({','=>''}))
end
def test_gen1
assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''}))
end
def test_gen3
assert_equal(%q("="=>""), @column.class.hstore_to_string({'='=>''}))
end
def test_gen2
assert_equal(%q(","=>""), @column.class.hstore_to_string({','=>''}))
end
def test_gen4
assert_equal(%q(">"=>""), @column.class.hstore_to_string({'>'=>''}))
end
def test_gen3
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_gen4
assert_equal(%q(">"=>""), @column.class.hstore_to_string({'>'=>''}))
end
def test_parse2
assert_equal({" " => " "}, @column.type_cast("\\ =>\\ "))
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_parse3
assert_equal({"=" => ">"}, @column.type_cast("==>>"))
end
def test_parse2
assert_equal({" " => " "}, @column.type_cast("\\ =>\\ "))
end
def test_parse4
assert_equal({"=a"=>"q=w"}, @column.type_cast('\=a=>q=w'))
end
def test_parse3
assert_equal({"=" => ">"}, @column.type_cast("==>>"))
end
def test_parse5
assert_equal({"=a"=>"q=w"}, @column.type_cast('"=a"=>q\=w'))
end
def test_parse4
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_parse5
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_parse6
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_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.first
assert_equal({'1' => '2'}, x.tags)
end
def test_select
@connection.execute "insert into hstores (tags) VALUES ('1=>2')"
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.first
assert_equal({'1' => '2', '2' => '3'}, x.tags)
end
def test_select_multikey
@connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')"
x = Hstore.first
assert_equal({'1' => '2', '2' => '3'}, x.tags)
end
def test_create
assert_cycle('a' => 'b', '1' => '2')
end
def test_create
assert_cycle('a' => 'b', '1' => '2')
end
def test_nil
assert_cycle('a' => nil)
end
def test_nil
assert_cycle('a' => nil)
end
def test_quotes
assert_cycle('a' => 'b"ar', '1"foo' => '2')
end
def test_quotes
assert_cycle('a' => 'b"ar', '1"foo' => '2')
end
def test_whitespace
assert_cycle('a b' => 'b ar', '1"foo' => '2')
end
def test_whitespace
assert_cycle('a b' => 'b ar', '1"foo' => '2')
end
def test_backslash
assert_cycle('a\\b' => 'b\\ar', '1"foo' => '2')
end
def test_backslash
assert_cycle('a\\b' => 'b\\ar', '1"foo' => '2')
end
def test_comma
assert_cycle('a, b' => 'bar', '1"foo' => '2')
end
def test_comma
assert_cycle('a, b' => 'bar', '1"foo' => '2')
end
def test_arrow
assert_cycle('a=>b' => 'bar', '1"foo' => '2')
end
def test_arrow
assert_cycle('a=>b' => 'bar', '1"foo' => '2')
end
def test_quoting_special_characters
assert_cycle('ca' => 'cà', 'ac' => 'àc')
end
def test_quoting_special_characters
assert_cycle('ca' => 'cà', 'ac' => 'àc')
end
def test_multiline
assert_cycle("a\nb" => "c\nd")
def test_multiline
assert_cycle("a\nb" => "c\nd")
end
end
private
def assert_cycle hash
# test creation
x = Hstore.create!(:tags => hash)
x.reload
assert_equal(hash, x.tags)
# test updating
x = Hstore.create!(:tags => {})
x.tags = hash
x.save!
x.reload
assert_equal(hash, x.tags)
end
def assert_cycle(hash)
# test creation
x = Hstore.create!(:tags => hash)
x.reload
assert_equal(hash, x.tags)
# test updating
x = Hstore.create!(:tags => {})
x.tags = hash
x.save!
x.reload
assert_equal(hash, x.tags)
end
end
......@@ -14,20 +14,20 @@ def status
end
class StatementPoolTest < ActiveRecord::TestCase
def test_cache_is_per_pid
return skip('must support fork') unless Process.respond_to?(:fork)
if Process.respond_to?(:fork)
def test_cache_is_per_pid
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
end
end
def test_dealloc_does_not_raise_on_inactive_connection
......
......@@ -12,10 +12,6 @@ def test_group_by_date
end
def test_load_infinity_and_beyond
unless current_adapter?(:PostgreSQLAdapter)
return skip("only tested on postgresql")
end
d = Developer.find_by_sql("select 'infinity'::timestamp as updated_at")
assert d.first.updated_at.infinite?, 'timestamp should be infinite'
......@@ -26,10 +22,6 @@ def test_load_infinity_and_beyond
end
def test_save_infinity_and_beyond
unless current_adapter?(:PostgreSQLAdapter)
return skip("only tested on postgresql")
end
d = Developer.create!(:name => 'aaron', :updated_at => 1.0 / 0.0)
assert_equal(1.0 / 0.0, d.updated_at)
......@@ -85,9 +77,6 @@ def test_postgres_agrees_with_activerecord_about_precision
end
def test_bc_timestamp
unless current_adapter?(:PostgreSQLAdapter)
return skip("only tested on postgresql")
end
date = Date.new(0) - 1.second
Developer.create!(:name => "aaron", :updated_at => date)
assert_equal date, Developer.find_by_name("aaron").updated_at
......@@ -109,5 +98,4 @@ def activerecord_column_option(tablename, column_name, option)
end
result && result.send(option)
end
end
......@@ -12,10 +12,6 @@ class UUID < ActiveRecord::Base
def setup
@connection = ActiveRecord::Base.connection
unless @connection.supports_extensions?
return skip "do not test on PG without uuid-ossp"
end
unless @connection.extension_enabled?('uuid-ossp')
@connection.enable_extension 'uuid-ossp'
@connection.commit_db_transaction
......@@ -35,33 +31,35 @@ def teardown
@connection.execute 'drop table if exists pg_uuids'
end
def test_id_is_uuid
assert_equal :uuid, UUID.columns_hash['id'].type
assert UUID.primary_key
end
if ActiveRecord::Base.connection.supports_extensions?
def test_id_is_uuid
assert_equal :uuid, UUID.columns_hash['id'].type
assert UUID.primary_key
end
def test_id_has_a_default
u = UUID.create
assert_not_nil u.id
end
def test_id_has_a_default
u = UUID.create
assert_not_nil u.id
end
def test_auto_create_uuid
u = UUID.create
u.reload
assert_not_nil u.other_uuid
end
def test_auto_create_uuid
u = UUID.create
u.reload
assert_not_nil u.other_uuid
end
def test_pk_and_sequence_for_uuid_primary_key
pk, seq = @connection.pk_and_sequence_for('pg_uuids')
assert_equal 'id', pk
assert_equal nil, seq
end
def test_pk_and_sequence_for_uuid_primary_key
pk, seq = @connection.pk_and_sequence_for('pg_uuids')
assert_equal 'id', pk
assert_equal nil, seq
end
def test_schema_dumper_for_uuid_primary_key
schema = StringIO.new
ActiveRecord::SchemaDumper.dump(@connection, schema)
assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: "uuid_generate_v1\(\)"/, schema.string)
assert_match(/t\.uuid "other_uuid", default: "uuid_generate_v4\(\)"/, schema.string)
def test_schema_dumper_for_uuid_primary_key
schema = StringIO.new
ActiveRecord::SchemaDumper.dump(@connection, schema)
assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: "uuid_generate_v1\(\)"/, schema.string)
assert_match(/t\.uuid "other_uuid", default: "uuid_generate_v4\(\)"/, schema.string)
end
end
end
......@@ -74,6 +72,11 @@ def setup
@connection = ActiveRecord::Base.connection
@connection.reconnect!
unless @connection.extension_enabled?('uuid-ossp')
@connection.enable_extension 'uuid-ossp'
@connection.commit_db_transaction
end
@connection.transaction do
@connection.create_table('pg_uuids', id: false) do |t|
t.primary_key :id, :uuid, default: nil
......@@ -86,12 +89,14 @@ def teardown
@connection.execute 'drop table if exists pg_uuids'
end
def test_id_allows_default_override_via_nil
col_desc = @connection.execute("SELECT pg_get_expr(d.adbin, d.adrelid) as default
if ActiveRecord::Base.connection.supports_extensions?
def test_id_allows_default_override_via_nil
col_desc = @connection.execute("SELECT pg_get_expr(d.adbin, d.adrelid) as default
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attname='id' AND a.attrelid = 'pg_uuids'::regclass").first
assert_nil col_desc["default"]
assert_nil col_desc["default"]
end
end
end
......@@ -110,6 +115,11 @@ def setup
@connection = ActiveRecord::Base.connection
@connection.reconnect!
unless @connection.extension_enabled?('uuid-ossp')
@connection.enable_extension 'uuid-ossp'
@connection.commit_db_transaction
end
@connection.transaction do
@connection.create_table('pg_uuid_posts', id: :uuid) do |t|
t.string 'title'
......@@ -128,9 +138,11 @@ def teardown
end
end
def test_collection_association_with_uuid
post = UuidPost.create!
comment = post.uuid_comments.create!
assert post.uuid_comments.find(comment.id)
if ActiveRecord::Base.connection.supports_extensions?
def test_collection_association_with_uuid
post = UuidPost.create!
comment = post.uuid_comments.create!
assert post.uuid_comments.find(comment.id)
end
end
end
......@@ -3,20 +3,21 @@
module ActiveRecord::ConnectionAdapters
class SQLite3Adapter
class StatementPoolTest < ActiveRecord::TestCase
def test_cache_is_per_pid
return skip('must support fork') unless Process.respond_to?(:fork)
if Process.respond_to?(:fork)
def test_cache_is_per_pid
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
cache = StatementPool.new nil, 10
cache['foo'] = 'bar'
assert_equal 'bar', cache['foo']
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
pid = fork {
lookup = cache['foo'];
exit!(!lookup)
}
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
Process.waitpid pid
assert $?.success?, 'process should exit successfully'
end
end
end
end
......
......@@ -612,18 +612,17 @@ def test_unicode_column_name
assert_equal 'たこ焼き仮面', weird.なまえ
end
def test_respect_internal_encoding
if current_adapter?(:PostgreSQLAdapter)
skip 'pg does not respect internal encoding and always returns utf8'
end
old_default_internal = Encoding.default_internal
silence_warnings { Encoding.default_internal = "EUC-JP" }
unless current_adapter?(:PostgreSQLAdapter)
def test_respect_internal_encoding
old_default_internal = Encoding.default_internal
silence_warnings { Encoding.default_internal = "EUC-JP" }
Weird.reset_column_information
Weird.reset_column_information
assert_equal ["EUC-JP"], Weird.columns.map {|c| c.name.encoding.name }.uniq
ensure
silence_warnings { Encoding.default_internal = old_default_internal }
assert_equal ["EUC-JP"], Weird.columns.map {|c| c.name.encoding.name }.uniq
ensure
silence_warnings { Encoding.default_internal = old_default_internal }
end
end
def test_non_valid_identifier_column_name
......@@ -1362,34 +1361,33 @@ def test_marshalling_with_associations
assert_equal 1, post.comments.length
end
def test_marshal_between_processes
skip "can't marshal between processes when using an in-memory db" if in_memory_db?
skip "fork isn't supported" unless Process.respond_to?(:fork)
if Process.respond_to?(:fork) && !in_memory_db?
def test_marshal_between_processes
# Define a new model to ensure there are no caches
if self.class.const_defined?("Post", false)
flunk "there should be no post constant"
end
# Define a new model to ensure there are no caches
if self.class.const_defined?("Post", false)
flunk "there should be no post constant"
end
self.class.const_set("Post", Class.new(ActiveRecord::Base) {
has_many :comments
})
self.class.const_set("Post", Class.new(ActiveRecord::Base) {
has_many :comments
})
rd, wr = IO.pipe
rd, wr = IO.pipe
ActiveRecord::Base.connection_handler.clear_all_connections!
ActiveRecord::Base.connection_handler.clear_all_connections!
fork do
rd.close
post = Post.new
post.comments.build
wr.write Marshal.dump(post)
wr.close
end
fork do
rd.close
post = Post.new
post.comments.build
wr.write Marshal.dump(post)
wr.close
assert Marshal.load rd.read
rd.close
end
wr.close
assert Marshal.load rd.read
rd.close
end
def test_marshalling_new_record_round_trip_with_associations
......
......@@ -23,46 +23,45 @@ def setup
@listener = LogListener.new
@pk = Topic.columns.find { |c| c.primary }
ActiveSupport::Notifications.subscribe('sql.active_record', @listener)
skip_if_prepared_statement_caching_is_not_supported
end
def teardown
ActiveSupport::Notifications.unsubscribe(@listener)
end
def test_binds_are_logged
sub = @connection.substitute_at(@pk, 0)
binds = [[@pk, 1]]
sql = "select * from topics where id = #{sub}"
@connection.exec_query(sql, 'SQL', binds)
if ActiveRecord::Base.connection.supports_statement_cache?
def test_binds_are_logged
sub = @connection.substitute_at(@pk, 0)
binds = [[@pk, 1]]
sql = "select * from topics where id = #{sub}"
message = @listener.calls.find { |args| args[4][:sql] == sql }
assert_equal binds, message[4][:binds]
end
@connection.exec_query(sql, 'SQL', binds)
def test_find_one_uses_binds
Topic.find(1)
binds = [[@pk, 1]]
message = @listener.calls.find { |args| args[4][:binds] == binds }
assert message, 'expected a message with binds'
end
message = @listener.calls.find { |args| args[4][:sql] == sql }
assert_equal binds, message[4][:binds]
end
def test_logs_bind_vars
pk = Topic.columns.find { |x| x.primary }
def test_find_one_uses_binds
Topic.find(1)
binds = [[@pk, 1]]
message = @listener.calls.find { |args| args[4][:binds] == binds }
assert message, 'expected a message with binds'
end
payload = {
:name => 'SQL',
:sql => 'select * from topics where id = ?',
:binds => [[pk, 10]]
}
event = ActiveSupport::Notifications::Event.new(
'foo',
Time.now,
Time.now,
123,
payload)
def test_logs_bind_vars
pk = Topic.columns.find { |x| x.primary }
payload = {
:name => 'SQL',
:sql => 'select * from topics where id = ?',
:binds => [[pk, 10]]
}
event = ActiveSupport::Notifications::Event.new(
'foo',
Time.now,
Time.now,
123,
payload)
logger = Class.new(ActiveRecord::LogSubscriber) {
attr_reader :debugs
......@@ -78,12 +77,7 @@ def debug str
logger.sql event
assert_match([[pk.name, 10]].inspect, logger.debugs.first)
end
private
def skip_if_prepared_statement_caching_is_not_supported
skip('prepared statement caching is not supported') unless @connection.supports_statement_cache?
end
end
end
end
......@@ -26,25 +26,25 @@ def setup
assert ActiveRecord::Base.connection_handler.active_connections?
end
def test_connection_pool_per_pid
return skip('must support fork') unless Process.respond_to?(:fork)
if Process.respond_to?(:fork)
def test_connection_pool_per_pid
object_id = ActiveRecord::Base.connection.object_id
object_id = ActiveRecord::Base.connection.object_id
rd, wr = IO.pipe
rd, wr = IO.pipe
pid = fork {
rd.close
wr.write Marshal.dump ActiveRecord::Base.connection.object_id
wr.close
exit!
}
pid = fork {
rd.close
wr.write Marshal.dump ActiveRecord::Base.connection.object_id
wr.close
exit!
}
wr.close
Process.waitpid pid
assert_not_equal object_id, Marshal.load(rd.read)
rd.close
Process.waitpid pid
assert_not_equal object_id, Marshal.load(rd.read)
rd.close
end
end
def test_app_delegation
......
......@@ -7,7 +7,6 @@ class TestDisconnectedAdapter < ActiveRecord::TestCase
self.use_transactional_fixtures = false
def setup
skip "in-memory database mustn't disconnect" if in_memory_db?
@connection = ActiveRecord::Base.connection
end
......@@ -17,11 +16,13 @@ def teardown
ActiveRecord::Base.establish_connection(spec)
end
test "can't execute statements while disconnected" do
@connection.execute "SELECT count(*) from products"
@connection.disconnect!
assert_raises(ActiveRecord::StatementInvalid) do
unless in_memory_db?
test "can't execute statements while disconnected" do
@connection.execute "SELECT count(*) from products"
@connection.disconnect!
assert_raises(ActiveRecord::StatementInvalid) do
@connection.execute "SELECT count(*) from products"
end
end
end
end
......@@ -119,11 +119,11 @@ def test_initializes_runtime
Thread.new { assert_equal 0, ActiveRecord::LogSubscriber.runtime }.join
end
def test_binary_data_is_not_logged
skip if current_adapter?(:Mysql2Adapter)
Binary.create(data: 'some binary data')
wait
assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join)
unless current_adapter?(:Mysql2Adapter)
def test_binary_data_is_not_logged
Binary.create(data: 'some binary data')
wait
assert_match(/<16 bytes of binary data>/, @logger.logged(:debug).join)
end
end
end
......@@ -74,8 +74,8 @@ def test_create_table_with_defaults
assert_equal "hello", five.default unless mysql
end
def test_add_column_with_array
if current_adapter?(:PostgreSQLAdapter)
if current_adapter?(:PostgreSQLAdapter)
def test_add_column_with_array
connection.create_table :testings
connection.add_column :testings, :foo, :string, :array => true
......@@ -83,13 +83,9 @@ def test_add_column_with_array
array_column = columns.detect { |c| c.name == "foo" }
assert array_column.array
else
skip "array option only supported in PostgreSQLAdapter"
end
end
def test_create_table_with_array_column
if current_adapter?(:PostgreSQLAdapter)
def test_create_table_with_array_column
connection.create_table :testings do |t|
t.string :foo, :array => true
end
......@@ -98,8 +94,6 @@ def test_create_table_with_array_column
array_column = columns.detect { |c| c.name == "foo" }
assert array_column.array
else
skip "array option only supported in PostgreSQLAdapter"
end
end
......@@ -211,20 +205,18 @@ def test_create_table_without_a_block
connection.create_table table_name
end
def test_add_column_not_null_without_default
# Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
if current_adapter?(:SybaseAdapter, :SQLite3Adapter)
skip "not supported on #{connection.class}"
end
connection.create_table :testings do |t|
t.column :foo, :string
end
connection.add_column :testings, :bar, :string, :null => false
# Sybase, and SQLite3 will not allow you to add a NOT NULL
# column to a table without a default value.
unless current_adapter?(:SybaseAdapter, :SQLite3Adapter)
def test_add_column_not_null_without_default
connection.create_table :testings do |t|
t.column :foo, :string
end
connection.add_column :testings, :bar, :string, :null => false
assert_raise(ActiveRecord::StatementInvalid) do
connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
assert_raise(ActiveRecord::StatementInvalid) do
connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
end
end
end
......
......@@ -35,12 +35,12 @@ def test_add_remove_single_field_using_symbol_arguments
assert_no_column TestModel, :last_name
end
def test_unabstracted_database_dependent_types
skip "not supported" unless current_adapter?(:MysqlAdapter, :Mysql2Adapter)
add_column :test_models, :intelligence_quotient, :tinyint
TestModel.reset_column_information
assert_match(/tinyint/, TestModel.columns_hash['intelligence_quotient'].sql_type)
if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
def test_unabstracted_database_dependent_types
add_column :test_models, :intelligence_quotient, :tinyint
TestModel.reset_column_information
assert_match(/tinyint/, TestModel.columns_hash['intelligence_quotient'].sql_type)
end
end
# We specifically do a manual INSERT here, and then test only the SELECT
......@@ -95,22 +95,22 @@ def test_add_column_with_precision_and_scale
assert_equal 7, wealth_column.scale
end
def test_change_column_preserve_other_column_precision_and_scale
skip "only on sqlite3" unless current_adapter?(:SQLite3Adapter)
if current_adapter?(:SQLite3Adapter)
def test_change_column_preserve_other_column_precision_and_scale
connection.add_column 'test_models', 'last_name', :string
connection.add_column 'test_models', 'wealth', :decimal, :precision => 9, :scale => 7
connection.add_column 'test_models', 'last_name', :string
connection.add_column 'test_models', 'wealth', :decimal, :precision => 9, :scale => 7
wealth_column = TestModel.columns_hash['wealth']
assert_equal 9, wealth_column.precision
assert_equal 7, wealth_column.scale
wealth_column = TestModel.columns_hash['wealth']
assert_equal 9, wealth_column.precision
assert_equal 7, wealth_column.scale
connection.change_column 'test_models', 'last_name', :string, :null => false
TestModel.reset_column_information
connection.change_column 'test_models', 'last_name', :string, :null => false
TestModel.reset_column_information
wealth_column = TestModel.columns_hash['wealth']
assert_equal 9, wealth_column.precision
assert_equal 7, wealth_column.scale
wealth_column = TestModel.columns_hash['wealth']
assert_equal 9, wealth_column.precision
assert_equal 7, wealth_column.scale
end
end
def test_native_types
......@@ -163,13 +163,13 @@ def test_native_types
assert_kind_of BigDecimal, bob.wealth
end
def test_out_of_range_limit_should_raise
skip("MySQL and PostgreSQL only") unless current_adapter?(:MysqlAdapter, :Mysql2Adapter, :PostgreSQLAdapter)
assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, :limit => 10 }
if current_adapter?(:MysqlAdapter, :Mysql2Adapter, :PostgreSQLAdapter)
def test_out_of_range_limit_should_raise
assert_raise(ActiveRecordError) { add_column :test_models, :integer_too_big, :integer, :limit => 10 }
unless current_adapter?(:PostgreSQLAdapter)
assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :integer, :limit => 0xfffffffff }
unless current_adapter?(:PostgreSQLAdapter)
assert_raise(ActiveRecordError) { add_column :test_models, :text_too_big, :integer, :limit => 0xfffffffff }
end
end
end
end
......
......@@ -9,10 +9,6 @@ class ColumnPositioningTest < ActiveRecord::TestCase
def setup
super
unless current_adapter?(:MysqlAdapter, :Mysql2Adapter)
skip "not supported on #{connection.class}"
end
@connection = ActiveRecord::Base.connection
connection.create_table :testings, :id => false do |t|
......@@ -28,33 +24,34 @@ def teardown
ActiveRecord::Base.primary_key_prefix_type = nil
end
def test_column_positioning
assert_equal %w(first second third), conn.columns(:testings).map {|c| c.name }
end
if current_adapter?(:MysqlAdapter, :Mysql2Adapter)
def test_column_positioning
assert_equal %w(first second third), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning
conn.add_column :testings, :new_col, :integer
assert_equal %w(first second third new_col), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning
conn.add_column :testings, :new_col, :integer
assert_equal %w(first second third new_col), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning_first
conn.add_column :testings, :new_col, :integer, :first => true
assert_equal %w(new_col first second third), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning_first
conn.add_column :testings, :new_col, :integer, :first => true
assert_equal %w(new_col first second third), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning_after
conn.add_column :testings, :new_col, :integer, :after => :first
assert_equal %w(first new_col second third), conn.columns(:testings).map {|c| c.name }
end
def test_add_column_with_positioning_after
conn.add_column :testings, :new_col, :integer, :after => :first
assert_equal %w(first new_col second third), conn.columns(:testings).map {|c| c.name }
end
def test_change_column_with_positioning
conn.change_column :testings, :second, :integer, :first => true
assert_equal %w(second first third), conn.columns(:testings).map {|c| c.name }
def test_change_column_with_positioning
conn.change_column :testings, :second, :integer, :first => true
assert_equal %w(second first third), conn.columns(:testings).map {|c| c.name }
conn.change_column :testings, :second, :integer, :after => :third
assert_equal %w(first third second), conn.columns(:testings).map {|c| c.name }
conn.change_column :testings, :second, :integer, :after => :third
assert_equal %w(first third second), conn.columns(:testings).map {|c| c.name }
end
end
end
end
end
......@@ -27,32 +27,28 @@ def teardown
ActiveRecord::Base.primary_key_prefix_type = nil
end
def test_rename_index
skip "not supported on openbase" if current_adapter?(:OpenBaseAdapter)
# keep the names short to make Oracle and similar behave
connection.add_index(table_name, [:foo], :name => 'old_idx')
connection.rename_index(table_name, 'old_idx', 'new_idx')
# if the adapter doesn't support the indexes call, pick defaults that let the test pass
assert_not connection.index_name_exists?(table_name, 'old_idx', false)
assert connection.index_name_exists?(table_name, 'new_idx', true)
end
def test_double_add_index
skip "not supported on openbase" if current_adapter?(:OpenBaseAdapter)
unless current_adapter?(:OpenBaseAdapter)
def test_rename_index
# keep the names short to make Oracle and similar behave
connection.add_index(table_name, [:foo], :name => 'old_idx')
connection.rename_index(table_name, 'old_idx', 'new_idx')
# if the adapter doesn't support the indexes call, pick defaults that let the test pass
assert_not connection.index_name_exists?(table_name, 'old_idx', false)
assert connection.index_name_exists?(table_name, 'new_idx', true)
end
connection.add_index(table_name, [:foo], :name => 'some_idx')
assert_raises(ArgumentError) {
def test_double_add_index
connection.add_index(table_name, [:foo], :name => 'some_idx')
}
end
def test_remove_nonexistent_index
skip "not supported on openbase" if current_adapter?(:OpenBaseAdapter)
assert_raises(ArgumentError) {
connection.add_index(table_name, [:foo], :name => 'some_idx')
}
end
# we do this by name, so OpenBase is a wash as noted above
assert_raise(ArgumentError) { connection.remove_index(table_name, "no_such_index") }
def test_remove_nonexistent_index
# we do this by name, so OpenBase is a wash as noted above
assert_raise(ArgumentError) { connection.remove_index(table_name, "no_such_index") }
end
end
def test_add_index_works_with_long_index_names
......
......@@ -50,14 +50,14 @@ def test_creates_index_with_options
assert connection.index_exists?(table_name, :bar_id, :name => :index_testings_on_bar_id, :unique => true)
end
def test_creates_polymorphic_index
return skip "Oracle Adapter does not support foreign keys if :polymorphic => true is used" if current_adapter? :OracleAdapter
unless current_adapter? :OracleAdapter
def test_creates_polymorphic_index
connection.create_table table_name do |t|
t.references :foo, :polymorphic => true, :index => true
end
connection.create_table table_name do |t|
t.references :foo, :polymorphic => true, :index => true
assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type)
end
assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type)
end
def test_creates_index_for_existing_table
......@@ -87,16 +87,16 @@ def test_does_not_create_index_for_existing_table_explicit
assert_not connection.index_exists?(table_name, :foo_id, :name => :index_testings_on_foo_id)
end
def test_creates_polymorphic_index_for_existing_table
return skip "Oracle Adapter does not support foreign keys if :polymorphic => true is used" if current_adapter? :OracleAdapter
connection.create_table table_name
connection.change_table table_name do |t|
t.references :foo, :polymorphic => true, :index => true
end
unless current_adapter? :OracleAdapter
def test_creates_polymorphic_index_for_existing_table
connection.create_table table_name
connection.change_table table_name do |t|
t.references :foo, :polymorphic => true, :index => true
end
assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type)
assert connection.index_exists?(table_name, [:foo_id, :foo_type], :name => :index_testings_on_foo_id_and_foo_type)
end
end
end
end
end
......@@ -19,24 +19,24 @@ def teardown
super
end
def test_rename_table_for_sqlite_should_work_with_reserved_words
renamed = false
skip "not supported" unless current_adapter?(:SQLite3Adapter)
add_column :test_models, :url, :string
connection.rename_table :references, :old_references
connection.rename_table :test_models, :references
renamed = true
# Using explicit id in insert for compatibility across all databases
connection.execute "INSERT INTO 'references' (url, created_at, updated_at) VALUES ('http://rubyonrails.com', 0, 0)"
assert_equal 'http://rubyonrails.com', connection.select_value("SELECT url FROM 'references' WHERE id=1")
ensure
return unless renamed
connection.rename_table :references, :test_models
connection.rename_table :old_references, :references
if current_adapter?(:SQLite3Adapter)
def test_rename_table_for_sqlite_should_work_with_reserved_words
renamed = false
add_column :test_models, :url, :string
connection.rename_table :references, :old_references
connection.rename_table :test_models, :references
renamed = true
# Using explicit id in insert for compatibility across all databases
connection.execute "INSERT INTO 'references' (url, created_at, updated_at) VALUES ('http://rubyonrails.com', 0, 0)"
assert_equal 'http://rubyonrails.com', connection.select_value("SELECT url FROM 'references' WHERE id=1")
ensure
return unless renamed
connection.rename_table :references, :test_models
connection.rename_table :old_references, :references
end
end
def test_rename_table
......@@ -76,14 +76,16 @@ def test_rename_table_does_not_rename_custom_named_index
assert_equal ['special_url_idx'], connection.indexes(:octopi).map(&:name)
end
def test_rename_table_for_postgresql_should_also_rename_default_sequence
skip 'not supported' unless current_adapter?(:PostgreSQLAdapter)
if current_adapter?(:PostgreSQLAdapter)
def test_rename_table_for_postgresql_should_also_rename_default_sequence
skip 'not supported'
rename_table :test_models, :octopi
rename_table :test_models, :octopi
pk, seq = connection.pk_and_sequence_for('octopi')
pk, seq = connection.pk_and_sequence_for('octopi')
assert_equal "octopi_#{pk}_seq", seq
assert_equal "octopi_#{pk}_seq", seq
end
end
end
end
......
......@@ -230,83 +230,73 @@ def test_instance_based_migration_down
assert migration.went_down, 'have not gone down'
end
def test_migrator_one_up_with_exception_and_rollback
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"
end
assert_no_column Person, :last_name
migration = Class.new(ActiveRecord::Migration) {
def version; 100 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
if ActiveRecord::Base.connection.supports_ddl_transactions?
def test_migrator_one_up_with_exception_and_rollback
assert_no_column Person, :last_name
migration = Class.new(ActiveRecord::Migration) {
def version; 100 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
e = assert_raise(StandardError) { migrator.migrate }
e = assert_raise(StandardError) { migrator.migrate }
assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message
assert_equal "An error has occurred, this and all later migrations canceled:\n\nSomething broke", e.message
assert_no_column Person, :last_name,
"On error, the Migrator should revert schema changes but it did not."
end
def test_migrator_one_up_with_exception_and_rollback_using_run
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"
assert_no_column Person, :last_name,
"On error, the Migrator should revert schema changes but it did not."
end
assert_no_column Person, :last_name
def test_migrator_one_up_with_exception_and_rollback_using_run
assert_no_column Person, :last_name
migration = Class.new(ActiveRecord::Migration) {
def version; 100 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
migration = Class.new(ActiveRecord::Migration) {
def version; 100 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
e = assert_raise(StandardError) { migrator.run }
migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
assert_equal "An error has occurred, this migration was canceled:\n\nSomething broke", e.message
e = assert_raise(StandardError) { migrator.run }
assert_no_column Person, :last_name,
"On error, the Migrator should revert schema changes but it did not."
end
assert_equal "An error has occurred, this migration was canceled:\n\nSomething broke", e.message
def test_migration_without_transaction
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"
assert_no_column Person, :last_name,
"On error, the Migrator should revert schema changes but it did not."
end
assert_no_column Person, :last_name
def test_migration_without_transaction
assert_no_column Person, :last_name
migration = Class.new(ActiveRecord::Migration) {
self.disable_ddl_transaction!
migration = Class.new(ActiveRecord::Migration) {
self.disable_ddl_transaction!
def version; 101 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
def version; 101 end
def migrate(x)
add_column "people", "last_name", :string
raise 'Something broke'
end
}.new
migrator = ActiveRecord::Migrator.new(:up, [migration], 101)
e = assert_raise(StandardError) { migrator.migrate }
assert_equal "An error has occurred, all later migrations canceled:\n\nSomething broke", e.message
migrator = ActiveRecord::Migrator.new(:up, [migration], 101)
e = assert_raise(StandardError) { migrator.migrate }
assert_equal "An error has occurred, all later migrations canceled:\n\nSomething broke", e.message
assert_column Person, :last_name,
"without ddl transactions, the Migrator should not rollback on error but it did."
ensure
Person.reset_column_information
if Person.column_names.include?('last_name')
Person.connection.remove_column('people', 'last_name')
assert_column Person, :last_name,
"without ddl transactions, the Migrator should not rollback on error but it did."
ensure
Person.reset_column_information
if Person.column_names.include?('last_name')
Person.connection.remove_column('people', 'last_name')
end
end
end
......@@ -450,62 +440,64 @@ def test_create_table_with_binary_column
Person.connection.drop_table :binary_testings rescue nil
end
def test_create_table_with_custom_sequence_name
skip "not supported" unless current_adapter? :OracleAdapter
if current_adapter? :OracleAdapter
def test_create_table_with_custom_sequence_name
skip "not supported"
# table name is 29 chars, the standard sequence name will
# be 33 chars and should be shortened
assert_nothing_raised do
begin
Person.connection.create_table :table_with_name_thats_just_ok do |t|
t.column :foo, :string, :null => false
# table name is 29 chars, the standard sequence name will
# be 33 chars and should be shortened
assert_nothing_raised do
begin
Person.connection.create_table :table_with_name_thats_just_ok do |t|
t.column :foo, :string, :null => false
end
ensure
Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
end
ensure
Person.connection.drop_table :table_with_name_thats_just_ok rescue nil
end
end
# should be all good w/ a custom sequence name
assert_nothing_raised do
begin
Person.connection.create_table :table_with_name_thats_just_ok,
:sequence_name => 'suitably_short_seq' do |t|
t.column :foo, :string, :null => false
end
# should be all good w/ a custom sequence name
assert_nothing_raised do
begin
Person.connection.create_table :table_with_name_thats_just_ok,
:sequence_name => 'suitably_short_seq' do |t|
t.column :foo, :string, :null => false
end
Person.connection.execute("select suitably_short_seq.nextval from dual")
Person.connection.execute("select suitably_short_seq.nextval from dual")
ensure
Person.connection.drop_table :table_with_name_thats_just_ok,
:sequence_name => 'suitably_short_seq' rescue nil
ensure
Person.connection.drop_table :table_with_name_thats_just_ok,
:sequence_name => 'suitably_short_seq' rescue nil
end
end
end
# confirm the custom sequence got dropped
assert_raise(ActiveRecord::StatementInvalid) do
Person.connection.execute("select suitably_short_seq.nextval from dual")
# confirm the custom sequence got dropped
assert_raise(ActiveRecord::StatementInvalid) do
Person.connection.execute("select suitably_short_seq.nextval from dual")
end
end
end
def test_out_of_range_limit_should_raise
skip("MySQL and PostgreSQL only") unless current_adapter?(:MysqlAdapter, :Mysql2Adapter, :PostgreSQLAdapter)
Person.connection.drop_table :test_limits rescue nil
assert_raise(ActiveRecord::ActiveRecordError, "integer limit didn't raise") do
Person.connection.create_table :test_integer_limits, :force => true do |t|
t.column :bigone, :integer, :limit => 10
if current_adapter?(:MysqlAdapter, :Mysql2Adapter, :PostgreSQLAdapter)
def test_out_of_range_limit_should_raise
Person.connection.drop_table :test_limits rescue nil
assert_raise(ActiveRecord::ActiveRecordError, "integer limit didn't raise") do
Person.connection.create_table :test_integer_limits, :force => true do |t|
t.column :bigone, :integer, :limit => 10
end
end
end
unless current_adapter?(:PostgreSQLAdapter)
assert_raise(ActiveRecord::ActiveRecordError, "text limit didn't raise") do
Person.connection.create_table :test_text_limits, :force => true do |t|
t.column :bigtext, :text, :limit => 0xfffffffff
unless current_adapter?(:PostgreSQLAdapter)
assert_raise(ActiveRecord::ActiveRecordError, "text limit didn't raise") do
Person.connection.create_table :test_text_limits, :force => true do |t|
t.column :bigtext, :text, :limit => 0xfffffffff
end
end
end
end
Person.connection.drop_table :test_limits rescue nil
Person.connection.drop_table :test_limits rescue nil
end
end
protected
......
......@@ -268,12 +268,12 @@ def test_multiparameter_attributes_on_time_with_empty_seconds
end
end
def test_multiparameter_attributes_setting_time_attribute
return skip "Oracle does not have TIME data type" if current_adapter? :OracleAdapter
topic = Topic.new( "bonus_time(4i)"=> "01", "bonus_time(5i)" => "05" )
assert_equal 1, topic.bonus_time.hour
assert_equal 5, topic.bonus_time.min
unless current_adapter? :OracleAdapter
def test_multiparameter_attributes_setting_time_attribute
topic = Topic.new( "bonus_time(4i)"=> "01", "bonus_time(5i)" => "05" )
assert_equal 1, topic.bonus_time.hour
assert_equal 5, topic.bonus_time.min
end
end
def test_multiparameter_attributes_setting_date_attribute
......
......@@ -185,19 +185,21 @@ def test_models_with_same_table_have_different_columns
class PrimaryKeyWithNoConnectionTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
def test_set_primary_key_with_no_connection
return skip("disconnect wipes in-memory db") if in_memory_db?
unless in_memory_db?
def test_set_primary_key_with_no_connection
return skip("disconnect wipes in-memory db")
connection = ActiveRecord::Base.remove_connection
connection = ActiveRecord::Base.remove_connection
model = Class.new(ActiveRecord::Base)
model.primary_key = 'foo'
model = Class.new(ActiveRecord::Base)
model.primary_key = 'foo'
assert_equal 'foo', model.primary_key
assert_equal 'foo', model.primary_key
ActiveRecord::Base.establish_connection(connection)
ActiveRecord::Base.establish_connection(connection)
assert_equal 'foo', model.primary_key
assert_equal 'foo', model.primary_key
end
end
end
......@@ -212,7 +214,6 @@ def test_primary_key_method_with_ansi_quotes
ensure
con.reconnect!
end
end
end
......@@ -252,19 +252,20 @@ def test_schema_dump_includes_bigint_default
assert_match %r{t.integer\s+"bigint_default",\s+limit: 8,\s+default: 0}, output
end
def test_schema_dump_includes_extensions
connection = ActiveRecord::Base.connection
skip unless connection.supports_extensions?
connection.stubs(:extensions).returns(['hstore'])
output = standard_dump
assert_match "# These are extensions that must be enabled", output
assert_match %r{enable_extension "hstore"}, output
connection.stubs(:extensions).returns([])
output = standard_dump
assert_no_match "# These are extensions that must be enabled", output
assert_no_match %r{enable_extension}, output
if ActiveRecord::Base.connection.supports_extensions?
def test_schema_dump_includes_extensions
connection = ActiveRecord::Base.connection
connection.stubs(:extensions).returns(['hstore'])
output = standard_dump
assert_match "# These are extensions that must be enabled", output
assert_match %r{enable_extension "hstore"}, output
connection.stubs(:extensions).returns([])
output = standard_dump
assert_no_match "# These are extensions that must be enabled", output
assert_no_match %r{enable_extension}, output
end
end
def test_schema_dump_includes_xml_shorthand_definition
......
......@@ -54,14 +54,14 @@ def test_default_scope_with_conditions_hash
assert_equal 'Jamis', DeveloperCalledJamis.create!.name
end
def test_default_scoping_with_threads
skip "in-memory database mustn't disconnect" if in_memory_db?
2.times do
Thread.new {
assert DeveloperOrderedBySalary.all.to_sql.include?('salary DESC')
DeveloperOrderedBySalary.connection.close
}.join
unless in_memory_db?
def test_default_scoping_with_threads
2.times do
Thread.new {
assert DeveloperOrderedBySalary.all.to_sql.include?('salary DESC')
DeveloperOrderedBySalary.connection.close
}.join
end
end
end
......@@ -362,23 +362,21 @@ def test_default_scope_include_with_count
assert_equal 1, DeveloperWithIncludes.where(:audit_logs => { :message => 'foo' }).count
end
def test_default_scope_is_threadsafe
if in_memory_db?
skip "in memory db can't share a db between threads"
unless in_memory_db?
def test_default_scope_is_threadsafe
threads = []
assert_not_equal 1, ThreadsafeDeveloper.unscoped.count
threads << Thread.new do
Thread.current[:long_default_scope] = true
assert_equal 1, ThreadsafeDeveloper.all.to_a.count
ThreadsafeDeveloper.connection.close
end
threads << Thread.new do
assert_equal 1, ThreadsafeDeveloper.all.to_a.count
ThreadsafeDeveloper.connection.close
end
threads.each(&:join)
end
threads = []
assert_not_equal 1, ThreadsafeDeveloper.unscoped.count
threads << Thread.new do
Thread.current[:long_default_scope] = true
assert_equal 1, ThreadsafeDeveloper.all.to_a.count
ThreadsafeDeveloper.connection.close
end
threads << Thread.new do
assert_equal 1, ThreadsafeDeveloper.all.to_a.count
ThreadsafeDeveloper.connection.close
end
threads.each(&:join)
end
end
......@@ -65,99 +65,98 @@ def test_create_when_database_exists_outputs_info_to_stderr
end
end
class MysqlDBCreateAsRootTest < ActiveRecord::TestCase
def setup
unless current_adapter?(:MysqlAdapter)
return skip("only tested on mysql")
if current_adapter?(:MysqlAdapter)
class MysqlDBCreateAsRootTest < ActiveRecord::TestCase
def setup
@connection = stub("Connection", create_database: true)
@error = Mysql::Error.new "Invalid permissions"
@configuration = {
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'wossname'
}
$stdin.stubs(:gets).returns("secret\n")
$stdout.stubs(:print).returns(nil)
@error.stubs(:errno).returns(1045)
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).
raises(@error).
then.returns(true)
end
@connection = stub("Connection", create_database: true)
@error = Mysql::Error.new "Invalid permissions"
@configuration = {
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'wossname'
}
if defined?(::Mysql)
def test_root_password_is_requested
assert_permissions_granted_for "pat"
$stdin.expects(:gets).returns("secret\n")
$stdin.stubs(:gets).returns("secret\n")
$stdout.stubs(:print).returns(nil)
@error.stubs(:errno).returns(1045)
ActiveRecord::Base.stubs(:connection).returns(@connection)
ActiveRecord::Base.stubs(:establish_connection).
raises(@error).
then.returns(true)
end
def test_root_password_is_requested
assert_permissions_granted_for "pat"
skip "only if mysql is available" unless defined?(::Mysql)
$stdin.expects(:gets).returns("secret\n")
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_connection_established_as_root
assert_permissions_granted_for "pat"
ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => nil,
'username' => 'root',
'password' => 'secret'
)
def test_connection_established_as_root
assert_permissions_granted_for "pat"
ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => nil,
'username' => 'root',
'password' => 'secret'
)
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_database_created_by_root
assert_permissions_granted_for "pat"
@connection.expects(:create_database).
with('my-app-db', :charset => 'utf8', :collation => 'utf8_unicode_ci')
def test_database_created_by_root
assert_permissions_granted_for "pat"
@connection.expects(:create_database).
with('my-app-db', :charset => 'utf8', :collation => 'utf8_unicode_ci')
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_grant_privileges_for_normal_user
assert_permissions_granted_for "pat"
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_grant_privileges_for_normal_user
assert_permissions_granted_for "pat"
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_do_not_grant_privileges_for_root_user
@configuration['username'] = 'root'
@configuration['password'] = ''
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_do_not_grant_privileges_for_root_user
@configuration['username'] = 'root'
@configuration['password'] = ''
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_connection_established_as_normal_user
assert_permissions_granted_for "pat"
ActiveRecord::Base.expects(:establish_connection).returns do
ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'secret'
)
def test_connection_established_as_normal_user
assert_permissions_granted_for "pat"
ActiveRecord::Base.expects(:establish_connection).returns do
ActiveRecord::Base.expects(:establish_connection).with(
'adapter' => 'mysql',
'database' => 'my-app-db',
'username' => 'pat',
'password' => 'secret'
)
raise @error
end
raise @error
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
def test_sends_output_to_stderr_when_other_errors
@error.stubs(:errno).returns(42)
def test_sends_output_to_stderr_when_other_errors
@error.stubs(:errno).returns(42)
$stderr.expects(:puts).at_least_once.returns(nil)
$stderr.expects(:puts).at_least_once.returns(nil)
ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
ActiveRecord::Tasks::DatabaseTasks.create @configuration
private
def assert_permissions_granted_for(db_user)
db_name = @configuration['database']
db_password = @configuration['password']
@connection.expects(:execute).with("GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_password}' WITH GRANT OPTION;")
end
end
private
def assert_permissions_granted_for(db_user)
db_name = @configuration['database']
db_password = @configuration['password']
@connection.expects(:execute).with("GRANT ALL PRIVILEGES ON #{db_name}.* TO '#{db_user}'@'localhost' IDENTIFIED BY '#{db_password}' WITH GRANT OPTION;")
end
end
class MySQLDBDropTest < ActiveRecord::TestCase
......
require 'cases/helper'
class TransactionIsolationUnsupportedTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
unless ActiveRecord::Base.connection.supports_transaction_isolation?
class TransactionIsolationUnsupportedTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
class Tag < ActiveRecord::Base
end
setup do
if ActiveRecord::Base.connection.supports_transaction_isolation?
skip "database supports transaction isolation; test is irrelevant"
class Tag < ActiveRecord::Base
end
end
test "setting the isolation level raises an error" do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(isolation: :serializable) { }
test "setting the isolation level raises an error" do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(isolation: :serializable) { }
end
end
end
end
class TransactionIsolationTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
class Tag < ActiveRecord::Base
self.table_name = 'tags'
end
class Tag2 < ActiveRecord::Base
self.table_name = 'tags'
end
if ActiveRecord::Base.connection.supports_transaction_isolation?
class TransactionIsolationTest < ActiveRecord::TestCase
self.use_transactional_fixtures = false
setup do
unless ActiveRecord::Base.connection.supports_transaction_isolation?
skip "database does not support setting transaction isolation"
class Tag < ActiveRecord::Base
self.table_name = 'tags'
end
Tag.establish_connection 'arunit'
Tag2.establish_connection 'arunit'
Tag.destroy_all
end
# It is impossible to properly test read uncommitted. The SQL standard only
# specifies what must not happen at a certain level, not what must happen. At
# the read uncommitted level, there is nothing that must not happen.
test "read uncommitted" do
unless ActiveRecord::Base.connection.transaction_isolation_levels.include?(:read_uncommitted)
skip "database does not support read uncommitted isolation level"
class Tag2 < ActiveRecord::Base
self.table_name = 'tags'
end
Tag.transaction(isolation: :read_uncommitted) do
assert_equal 0, Tag.count
Tag2.create
assert_equal 1, Tag.count
setup do
Tag.establish_connection 'arunit'
Tag2.establish_connection 'arunit'
Tag.destroy_all
end
end
# We are testing that a dirty read does not happen
test "read committed" do
Tag.transaction(isolation: :read_committed) do
assert_equal 0, Tag.count
# It is impossible to properly test read uncommitted. The SQL standard only
# specifies what must not happen at a certain level, not what must happen. At
# the read uncommitted level, there is nothing that must not happen.
if ActiveRecord::Base.connection.transaction_isolation_levels.include?(:read_uncommitted)
test "read uncommitted" do
Tag.transaction(isolation: :read_uncommitted) do
assert_equal 0, Tag.count
Tag2.create
assert_equal 1, Tag.count
end
end
end
Tag2.transaction do
Tag2.create
# We are testing that a dirty read does not happen
test "read committed" do
Tag.transaction(isolation: :read_committed) do
assert_equal 0, Tag.count
Tag2.transaction do
Tag2.create
assert_equal 0, Tag.count
end
end
assert_equal 1, Tag.count
end
assert_equal 1, Tag.count
end
# We are testing that a nonrepeatable read does not happen
if ActiveRecord::Base.connection.transaction_isolation_levels.include?(:repeatable_read)
test "repeatable read" do
tag = Tag.create(name: 'jon')
# We are testing that a nonrepeatable read does not happen
test "repeatable read" do
unless ActiveRecord::Base.connection.transaction_isolation_levels.include?(:repeatable_read)
skip "database does not support repeatable read isolation level"
end
tag = Tag.create(name: 'jon')
Tag.transaction(isolation: :repeatable_read) do
tag.reload
Tag2.find(tag.id).update(name: 'emily')
Tag.transaction(isolation: :repeatable_read) do
tag.reload
Tag2.find(tag.id).update(name: 'emily')
tag.reload
assert_equal 'jon', tag.name
end
tag.reload
assert_equal 'jon', tag.name
tag.reload
assert_equal 'emily', tag.name
end
end
tag.reload
assert_equal 'emily', tag.name
end
# We are only testing that there are no errors because it's too hard to
# test serializable. Databases behave differently to enforce the serializability
# constraint.
test "serializable" do
Tag.transaction(isolation: :serializable) do
Tag.create
# We are only testing that there are no errors because it's too hard to
# test serializable. Databases behave differently to enforce the serializability
# constraint.
test "serializable" do
Tag.transaction(isolation: :serializable) do
Tag.create
end
end
end
test "setting isolation when joining a transaction raises an error" do
Tag.transaction do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(isolation: :serializable) { }
test "setting isolation when joining a transaction raises an error" do
Tag.transaction do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(isolation: :serializable) { }
end
end
end
end
test "setting isolation when starting a nested transaction raises error" do
Tag.transaction do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(requires_new: true, isolation: :serializable) { }
test "setting isolation when starting a nested transaction raises error" do
Tag.transaction do
assert_raises(ActiveRecord::TransactionIsolationError) do
Tag.transaction(requires_new: true, isolation: :serializable) { }
end
end
end
end
......
......@@ -571,23 +571,23 @@ def test_no_automatic_savepoint_for_inner_transaction
class ConcurrentTransactionTest < TransactionTest
# This will cause transactions to overlap and fail unless they are performed on
# separate database connections.
def test_transaction_per_thread
skip "in memory db can't share a db between threads" if in_memory_db?
threads = 3.times.map do
Thread.new do
Topic.transaction do
topic = Topic.find(1)
topic.approved = !topic.approved?
assert topic.save!
topic.approved = !topic.approved?
assert topic.save!
unless in_memory_db?
def test_transaction_per_thread
threads = 3.times.map do
Thread.new do
Topic.transaction do
topic = Topic.find(1)
topic.approved = !topic.approved?
assert topic.save!
topic.approved = !topic.approved?
assert topic.save!
end
Topic.connection.close
end
Topic.connection.close
end
end
threads.each { |t| t.join }
threads.each { |t| t.join }
end
end
# Test for dirty reads among simultaneous transactions.
......
......@@ -365,15 +365,15 @@ def test_validate_uniqueness_with_non_callable_conditions_is_not_supported
}
end
def test_validate_uniqueness_with_array_column
return skip "Uniqueness on arrays has only been tested in PostgreSQL so far." if !current_adapter? :PostgreSQLAdapter
e1 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [1000, 1200])
assert e1.persisted?, "Saving e1"
e2 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [2200])
assert !e2.persisted?, "e2 shouldn't be valid"
assert e2.errors[:nicknames].any?, "Should have errors for nicknames"
assert_equal ["has already been taken"], e2.errors[:nicknames], "Should have uniqueness message for nicknames"
if current_adapter? :PostgreSQLAdapter
def test_validate_uniqueness_with_array_column
e1 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [1000, 1200])
assert e1.persisted?, "Saving e1"
e2 = Employee.create("nicknames" => ["john", "johnny"], "commission_by_quarter" => [2200])
assert !e2.persisted?, "e2 shouldn't be valid"
assert e2.errors[:nicknames].any?, "Should have errors for nicknames"
assert_equal ["has already been taken"], e2.errors[:nicknames], "Should have uniqueness message for nicknames"
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册