From 87f560978d8e0c7095a3040995c2e9a97e3e3729 Mon Sep 17 00:00:00 2001 From: takanamito Date: Sun, 12 Jan 2020 17:54:15 +0900 Subject: [PATCH 1/9] Use rails backtrace in tests --- test/cases/helper_sqlserver.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/cases/helper_sqlserver.rb b/test/cases/helper_sqlserver.rb index 677c40bf7..028648c37 100644 --- a/test/cases/helper_sqlserver.rb +++ b/test/cases/helper_sqlserver.rb @@ -25,6 +25,7 @@ class TestCase < ActiveSupport::TestCase let(:logger) { ActiveRecord::Base.logger } setup :ensure_clean_rails_env + setup :remove_backtrace_silencers private @@ -32,6 +33,10 @@ def ensure_clean_rails_env Rails.instance_variable_set(:@_env, nil) if defined?(::Rails) end + def remove_backtrace_silencers + Rails.backtrace_cleaner.remove_silencers! + end + def host_windows? RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ end From a0c301cd73b82ca650bdbc202cdd20cfa6efcdb4 Mon Sep 17 00:00:00 2001 From: takanamito Date: Sun, 12 Jan 2020 18:14:51 +0900 Subject: [PATCH 2/9] Prepare for Minitest6 --- test/cases/adapter_test_sqlserver.rb | 36 +- .../change_column_null_test_sqlserver.rb | 8 +- test/cases/column_test_sqlserver.rb | 908 +++++++++--------- test/cases/connection_test_sqlserver.rb | 4 +- test/cases/fetch_test_sqlserver.rb | 10 +- test/cases/json_test_sqlserver.rb | 12 +- test/cases/migration_test_sqlserver.rb | 4 +- .../pessimistic_locking_test_sqlserver.rb | 18 +- test/cases/rake_test_sqlserver.rb | 40 +- test/cases/schema_dumper_test_sqlserver.rb | 66 +- test/cases/schema_test_sqlserver.rb | 4 +- test/cases/showplan_test_sqlserver.rb | 28 +- test/cases/specific_schema_test_sqlserver.rb | 22 +- test/cases/transaction_test_sqlserver.rb | 18 +- test/cases/trigger_test_sqlserver.rb | 16 +- test/cases/utils_test_sqlserver.rb | 72 +- test/cases/uuid_test_sqlserver.rb | 16 +- 17 files changed, 641 insertions(+), 641 deletions(-) diff --git a/test/cases/adapter_test_sqlserver.rb b/test/cases/adapter_test_sqlserver.rb index 34d75bce7..628a54140 100644 --- a/test/cases/adapter_test_sqlserver.rb +++ b/test/cases/adapter_test_sqlserver.rb @@ -15,14 +15,14 @@ class AdapterTestSQLServer < ActiveRecord::TestCase it 'has basic and non-senstive information in the adpaters inspect method' do string = connection.inspect - string.must_match %r{ActiveRecord::ConnectionAdapters::SQLServerAdapter} - string.must_match %r{version\: \d.\d} - string.must_match %r{mode: dblib} - string.must_match %r{azure: (true|false)} - string.wont_match %r{host} - string.wont_match %r{password} - string.wont_match %r{username} - string.wont_match %r{port} + _(string).must_match %r{ActiveRecord::ConnectionAdapters::SQLServerAdapter} + _(string).must_match %r{version\: \d.\d} + _(string).must_match %r{mode: dblib} + _(string).must_match %r{azure: (true|false)} + _(string).wont_match %r{host} + _(string).wont_match %r{password} + _(string).wont_match %r{username} + _(string).wont_match %r{port} end it 'has a 128 max #table_alias_length' do @@ -161,7 +161,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase end it 'return an empty array when calling #identity_columns for a table_name with no identity' do - connection.send(:identity_columns, Subscriber.table_name).must_equal [] + _(connection.send(:identity_columns, Subscriber.table_name)).must_equal [] end end @@ -303,7 +303,7 @@ class AdapterTestSQLServer < ActiveRecord::TestCase end it 'find SSTestCustomersView table name' do - connection.views.must_include 'sst_customers_view' + _(connection.views).must_include 'sst_customers_view' end it 'work with dynamic finders' do @@ -344,9 +344,9 @@ class AdapterTestSQLServer < ActiveRecord::TestCase end it 'find identity column' do - SSTestCustomersView.primary_key.must_equal 'id' - connection.primary_key(SSTestCustomersView.table_name).must_equal 'id' - SSTestCustomersView.columns_hash['id'].must_be :is_identity? + _(SSTestCustomersView.primary_key).must_equal 'id' + _(connection.primary_key(SSTestCustomersView.table_name)).must_equal 'id' + _(SSTestCustomersView.columns_hash['id']).must_be :is_identity? end it 'find default values' do @@ -371,9 +371,9 @@ class AdapterTestSQLServer < ActiveRecord::TestCase end it 'find identity column' do - SSTestStringDefaultsView.primary_key.must_equal 'id' - connection.primary_key(SSTestStringDefaultsView.table_name).must_equal 'id' - SSTestStringDefaultsView.columns_hash['id'].must_be :is_identity? + _(SSTestStringDefaultsView.primary_key).must_equal 'id' + _(connection.primary_key(SSTestStringDefaultsView.table_name)).must_equal 'id' + _(SSTestStringDefaultsView.columns_hash['id']).must_be :is_identity? end it 'find default values' do @@ -422,8 +422,8 @@ class AdapterTestSQLServer < ActiveRecord::TestCase it 'in_memory_oltp' do if ENV['IN_MEMORY_OLTP'] && connection.supports_in_memory_oltp? - SSTMemory.primary_key.must_equal 'id' - SSTMemory.columns_hash['id'].must_be :is_identity? + _(SSTMemory.primary_key).must_equal 'id' + _(SSTMemory.columns_hash['id']).must_be :is_identity? else skip 'supports_in_memory_oltp? => false' end diff --git a/test/cases/change_column_null_test_sqlserver.rb b/test/cases/change_column_null_test_sqlserver.rb index 60fcf1077..32ef027f9 100644 --- a/test/cases/change_column_null_test_sqlserver.rb +++ b/test/cases/change_column_null_test_sqlserver.rb @@ -24,19 +24,19 @@ def find_column(table, name) describe '#change_column_null' do it 'does not change the column limit' do - name_column.limit.must_equal 15 + _(name_column.limit).must_equal 15 end it 'does not change the column default' do - code_column.default.must_equal 'n/a' + _(code_column.default).must_equal 'n/a' end it 'does not change the column precision' do - value_column.precision.must_equal 32 + _(value_column.precision).must_equal 32 end it 'does not change the column scale' do - value_column.scale.must_equal 8 + _(value_column.scale).must_equal 8 end end end diff --git a/test/cases/column_test_sqlserver.rb b/test/cases/column_test_sqlserver.rb index e3f869135..796470436 100644 --- a/test/cases/column_test_sqlserver.rb +++ b/test/cases/column_test_sqlserver.rb @@ -18,9 +18,9 @@ def new_obj ; SSTestDatatype.new ; end def column(name) ; SSTestDatatype.columns_hash[name] ; end def assert_obj_set_and_save(attribute, value) obj.send :"#{attribute}=", value - obj.send(attribute).must_equal value + _(obj.send(attribute)).must_equal value obj.save! - obj.reload.send(attribute).must_equal value + _(obj.reload.send(attribute)).must_equal value end # http://msdn.microsoft.com/en-us/library/ms187752.aspx @@ -29,199 +29,199 @@ def assert_obj_set_and_save(attribute, value) it 'int(4) PRIMARY KEY' do col = column('id') - col.sql_type.must_equal 'int(4)' - col.null.must_equal false + _(col.sql_type).must_equal 'int(4)' + _(col.null).must_equal false end it 'bigint(8)' do col = column('bigint') - col.sql_type.must_equal 'bigint(8)' - col.type.must_equal :integer - col.null.must_equal true - col.default.must_equal 42 - obj.bigint.must_equal 42 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::BigInteger - type.limit.must_equal 8 + _(col.sql_type).must_equal 'bigint(8)' + _(col.type).must_equal :integer + _(col.null).must_equal true + _(col.default).must_equal 42 + _(obj.bigint).must_equal 42 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::BigInteger + _(type.limit).must_equal 8 assert_obj_set_and_save :bigint, -9_223_372_036_854_775_808 assert_obj_set_and_save :bigint, 9_223_372_036_854_775_807 end it 'int(4)' do col = column('int') - col.sql_type.must_equal 'int(4)' - col.type.must_equal :integer - col.null.must_equal true - col.default.must_equal 42 - obj.int.must_equal 42 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Integer - type.limit.must_equal 4 + _(col.sql_type).must_equal 'int(4)' + _(col.type).must_equal :integer + _(col.null).must_equal true + _(col.default).must_equal 42 + _(obj.int).must_equal 42 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Integer + _(type.limit).must_equal 4 assert_obj_set_and_save :int, -2_147_483_648 assert_obj_set_and_save :int, 2_147_483_647 end it 'smallint(2)' do col = column('smallint') - col.sql_type.must_equal 'smallint(2)' - col.type.must_equal :integer - col.null.must_equal true - col.default.must_equal 42 - obj.smallint.must_equal 42 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::SmallInteger - type.limit.must_equal 2 + _(col.sql_type).must_equal 'smallint(2)' + _(col.type).must_equal :integer + _(col.null).must_equal true + _(col.default).must_equal 42 + _(obj.smallint).must_equal 42 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::SmallInteger + _(type.limit).must_equal 2 assert_obj_set_and_save :smallint, -32_768 assert_obj_set_and_save :smallint, 32_767 end it 'tinyint(1)' do col = column('tinyint') - col.sql_type.must_equal 'tinyint(1)' - col.type.must_equal :integer - col.null.must_equal true - col.default.must_equal 42 - obj.tinyint.must_equal 42 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::TinyInteger - type.limit.must_equal 1 + _(col.sql_type).must_equal 'tinyint(1)' + _(col.type).must_equal :integer + _(col.null).must_equal true + _(col.default).must_equal 42 + _(obj.tinyint).must_equal 42 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::TinyInteger + _(type.limit).must_equal 1 assert_obj_set_and_save :tinyint, 0 assert_obj_set_and_save :tinyint, 255 end it 'bit' do col = column('bit') - col.sql_type.must_equal 'bit' - col.type.must_equal :boolean - col.null.must_equal true - col.default.must_equal true - obj.bit.must_equal true - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Boolean - type.limit.must_be_nil + _(col.sql_type).must_equal 'bit' + _(col.type).must_equal :boolean + _(col.null).must_equal true + _(col.default).must_equal true + _(obj.bit).must_equal true + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Boolean + _(type.limit).must_be_nil obj.bit = 0 - obj.bit.must_equal false + _(obj.bit).must_equal false obj.save! - obj.reload.bit.must_equal false + _(obj.reload.bit).must_equal false obj.bit = '1' - obj.bit.must_equal true + _(obj.bit).must_equal true obj.save! - obj.reload.bit.must_equal true + _(obj.reload.bit).must_equal true end it 'decimal(9,2)' do col = column('decimal_9_2') - col.sql_type.must_equal 'decimal(9,2)' - col.type.must_equal :decimal - col.null.must_equal true - col.default.must_equal BigDecimal('12345.01') - obj.decimal_9_2.must_equal BigDecimal('12345.01') - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Decimal - type.limit.must_be_nil - type.precision.must_equal 9 - type.scale.must_equal 2 + _(col.sql_type).must_equal 'decimal(9,2)' + _(col.type).must_equal :decimal + _(col.null).must_equal true + _(col.default).must_equal BigDecimal('12345.01') + _(obj.decimal_9_2).must_equal BigDecimal('12345.01') + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Decimal + _(type.limit).must_be_nil + _(type.precision).must_equal 9 + _(type.scale).must_equal 2 obj.decimal_9_2 = '1234567.8901' - obj.decimal_9_2.must_equal BigDecimal('1234567.89') + _(obj.decimal_9_2).must_equal BigDecimal('1234567.89') obj.save! - obj.reload.decimal_9_2.must_equal BigDecimal('1234567.89') + _(obj.reload.decimal_9_2).must_equal BigDecimal('1234567.89') end it 'decimal(16,4)' do col = column('decimal_16_4') - col.sql_type.must_equal 'decimal(16,4)' - col.default.must_equal BigDecimal('1234567.89') - obj.decimal_16_4.must_equal BigDecimal('1234567.89') - col.default_function.must_be_nil + _(col.sql_type).must_equal 'decimal(16,4)' + _(col.default).must_equal BigDecimal('1234567.89') + _(obj.decimal_16_4).must_equal BigDecimal('1234567.89') + _(col.default_function).must_be_nil type = connection.lookup_cast_type_from_column(col) - type.precision.must_equal 16 - type.scale.must_equal 4 + _(type.precision).must_equal 16 + _(type.scale).must_equal 4 obj.decimal_16_4 = '1234567.8901001' - obj.decimal_16_4.must_equal BigDecimal('1234567.8901') + _(obj.decimal_16_4).must_equal BigDecimal('1234567.8901') obj.save! - obj.reload.decimal_16_4.must_equal BigDecimal('1234567.8901') + _(obj.reload.decimal_16_4).must_equal BigDecimal('1234567.8901') end it 'numeric(18,0)' do col = column('numeric_18_0') - col.sql_type.must_equal 'numeric(18,0)' - col.type.must_equal :decimal - col.null.must_equal true - col.default.must_equal BigDecimal('191') - obj.numeric_18_0.must_equal BigDecimal('191') - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Decimal - type.limit.must_be_nil - type.precision.must_equal 18 - type.scale.must_equal 0 + _(col.sql_type).must_equal 'numeric(18,0)' + _(col.type).must_equal :decimal + _(col.null).must_equal true + _(col.default).must_equal BigDecimal('191') + _(obj.numeric_18_0).must_equal BigDecimal('191') + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Decimal + _(type.limit).must_be_nil + _(type.precision).must_equal 18 + _(type.scale).must_equal 0 obj.numeric_18_0 = '192.1' - obj.numeric_18_0.must_equal BigDecimal('192') + _(obj.numeric_18_0).must_equal BigDecimal('192') obj.save! - obj.reload.numeric_18_0.must_equal BigDecimal('192') + _(obj.reload.numeric_18_0).must_equal BigDecimal('192') end it 'numeric(36,2)' do col = column('numeric_36_2') - col.sql_type.must_equal 'numeric(36,2)' - col.type.must_equal :decimal - col.null.must_equal true - col.default.must_equal BigDecimal('12345678901234567890.01') - obj.numeric_36_2.must_equal BigDecimal('12345678901234567890.01') - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Decimal - type.limit.must_be_nil - type.precision.must_equal 36 - type.scale.must_equal 2 + _(col.sql_type).must_equal 'numeric(36,2)' + _(col.type).must_equal :decimal + _(col.null).must_equal true + _(col.default).must_equal BigDecimal('12345678901234567890.01') + _(obj.numeric_36_2).must_equal BigDecimal('12345678901234567890.01') + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Decimal + _(type.limit).must_be_nil + _(type.precision).must_equal 36 + _(type.scale).must_equal 2 obj.numeric_36_2 = '192.123' - obj.numeric_36_2.must_equal BigDecimal('192.12') + _(obj.numeric_36_2).must_equal BigDecimal('192.12') obj.save! - obj.reload.numeric_36_2.must_equal BigDecimal('192.12') + _(obj.reload.numeric_36_2).must_equal BigDecimal('192.12') end it 'money' do col = column('money') - col.sql_type.must_equal 'money' - col.type.must_equal :money - col.null.must_equal true - col.default.must_equal BigDecimal('4.20') - obj.money.must_equal BigDecimal('4.20') - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Money - type.limit.must_be_nil - type.precision.must_equal 19 - type.scale.must_equal 4 + _(col.sql_type).must_equal 'money' + _(col.type).must_equal :money + _(col.null).must_equal true + _(col.default).must_equal BigDecimal('4.20') + _(obj.money).must_equal BigDecimal('4.20') + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Money + _(type.limit).must_be_nil + _(type.precision).must_equal 19 + _(type.scale).must_equal 4 obj.money = '922337203685477.58061' - obj.money.must_equal BigDecimal('922337203685477.5806') + _(obj.money).must_equal BigDecimal('922337203685477.5806') obj.save! - obj.reload.money.must_equal BigDecimal('922337203685477.5806') + _(obj.reload.money).must_equal BigDecimal('922337203685477.5806') end it 'smallmoney' do col = column('smallmoney') - col.sql_type.must_equal 'smallmoney' - col.type.must_equal :smallmoney - col.null.must_equal true - col.default.must_equal BigDecimal('4.20') - obj.smallmoney.must_equal BigDecimal('4.20') - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::SmallMoney - type.limit.must_be_nil - type.precision.must_equal 10 - type.scale.must_equal 4 + _(col.sql_type).must_equal 'smallmoney' + _(col.type).must_equal :smallmoney + _(col.null).must_equal true + _(col.default).must_equal BigDecimal('4.20') + _(obj.smallmoney).must_equal BigDecimal('4.20') + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::SmallMoney + _(type.limit).must_be_nil + _(type.precision).must_equal 10 + _(type.scale).must_equal 4 obj.smallmoney = '214748.36461' - obj.smallmoney.must_equal BigDecimal('214748.3646') + _(obj.smallmoney).must_equal BigDecimal('214748.3646') obj.save! - obj.reload.smallmoney.must_equal BigDecimal('214748.3646') + _(obj.reload.smallmoney).must_equal BigDecimal('214748.3646') end # Approximate Numerics @@ -230,386 +230,386 @@ def assert_obj_set_and_save(attribute, value) it 'float' do col = column('float') - col.sql_type.must_equal 'float' - col.type.must_equal :float - col.null.must_equal true - col.default.must_equal 123.00000001 - obj.float.must_equal 123.00000001 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Float - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'float' + _(col.type).must_equal :float + _(col.null).must_equal true + _(col.default).must_equal 123.00000001 + _(obj.float).must_equal 123.00000001 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Float + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil obj.float = '214748.36461' - obj.float.must_equal 214748.36461 + _(obj.float).must_equal 214748.36461 obj.save! - obj.reload.float.must_equal 214748.36461 + _(obj.reload.float).must_equal 214748.36461 end it 'real' do col = column('real') - col.sql_type.must_equal 'real' - col.type.must_equal :real - col.null.must_equal true - col.default.must_be_close_to 123.45, 0.01 - obj.real.must_be_close_to 123.45, 0.01 - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Real - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'real' + _(col.type).must_equal :real + _(col.null).must_equal true + _(col.default).must_be_close_to 123.45, 0.01 + _(obj.real).must_be_close_to 123.45, 0.01 + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Real + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil obj.real = '214748.36461' - obj.real.must_be_close_to 214748.36461, 0.01 + _(obj.real).must_be_close_to 214748.36461, 0.01 obj.save! - obj.reload.real.must_be_close_to 214748.36461, 0.01 + _(obj.reload.real).must_be_close_to 214748.36461, 0.01 end # Date and Time it 'date' do col = column('date') - col.sql_type.must_equal 'date' - col.type.must_equal :date - col.null.must_equal true - col.default.must_equal connection_dblib_73? ? Date.civil(0001, 1, 1) : '0001-01-01' - obj.date.must_equal Date.civil(0001, 1, 1) - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Date - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'date' + _(col.type).must_equal :date + _(col.null).must_equal true + _(col.default).must_equal connection_dblib_73? ? Date.civil(0001, 1, 1) : '0001-01-01' + _(obj.date).must_equal Date.civil(0001, 1, 1) + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Date + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Can cast strings. SQL Server format. obj.date = '04-01-0001' - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) obj.save! - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) obj.reload - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) # Can cast strings. ISO format. obj.date = '0001-04-01' - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) obj.save! - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) obj.reload - obj.date.must_equal Date.civil(0001, 4, 1) + _(obj.date).must_equal Date.civil(0001, 4, 1) # Can keep and return assigned date. assert_obj_set_and_save :date, Date.civil(1972, 04, 14) # Can accept and cast time objects. obj.date = Time.utc(2010, 4, 14, 12, 34, 56, 3000) - obj.date.must_equal Date.civil(2010, 4, 14) + _(obj.date).must_equal Date.civil(2010, 4, 14) obj.save! - obj.reload.date.must_equal Date.civil(2010, 4, 14) + _(obj.reload.date).must_equal Date.civil(2010, 4, 14) end it 'datetime' do col = column('datetime') - col.sql_type.must_equal 'datetime' - col.type.must_equal :datetime - col.null.must_equal true + _(col.sql_type).must_equal 'datetime' + _(col.type).must_equal :datetime + _(col.null).must_equal true time = Time.utc 1753, 01, 01, 00, 00, 00, 123000 - col.default.must_equal time, "Microseconds were <#{col.default.usec}> vs <123000>" - obj.datetime.must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <123000>" - col.default_function.must_be_nil + _(col.default).must_equal time, "Microseconds were <#{col.default.usec}> vs <123000>" + _(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <123000>" + _(col.default_function).must_be_nil type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::DateTime - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(type).must_be_instance_of Type::DateTime + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil obj.save! - obj.must_equal obj.class.where(datetime: time).first + _(obj).must_equal obj.class.where(datetime: time).first # Can save to proper accuracy and return again. time = Time.utc 2010, 04, 01, 12, 34, 56, 3000 obj.datetime = time - obj.datetime.must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" + _(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" obj.save! - obj.datetime.must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" + _(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" obj.reload - obj.datetime.must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" - obj.must_equal obj.class.where(datetime: time).first + _(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <3000>" + _(obj).must_equal obj.class.where(datetime: time).first # Will cast to true DB value on attribute write, save and return again. time = Time.utc 2010, 04, 01, 12, 34, 56, 234567 time2 = Time.utc 2010, 04, 01, 12, 34, 56, 233000 obj.datetime = time - obj.datetime.must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" + _(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" obj.save! - obj.datetime.must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" + _(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" obj.reload - obj.datetime.must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" - obj.must_equal obj.class.where(datetime: time).first - obj.must_equal obj.class.where(datetime: time2).first + _(obj.datetime).must_equal time2, "Microseconds were <#{obj.datetime.usec}> vs <233000>" + _(obj).must_equal obj.class.where(datetime: time).first + _(obj).must_equal obj.class.where(datetime: time2).first # Set and find nil. obj.datetime = nil - obj.datetime.must_be_nil + _(obj.datetime).must_be_nil obj.save! - obj.datetime.must_be_nil - obj.must_equal obj.class.where(datetime: nil).first + _(obj.datetime).must_be_nil + _(obj).must_equal obj.class.where(datetime: nil).first end it 'datetime2' do skip 'datetime2 not supported in this protocal version' unless connection_dblib_73? col = column('datetime2_7') - col.sql_type.must_equal 'datetime2(7)' - col.type.must_equal :datetime - col.null.must_equal true + _(col.sql_type).must_equal 'datetime2(7)' + _(col.type).must_equal :datetime + _(col.null).must_equal true time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(999999900, 1000) - col.default.must_equal time, "Nanoseconds were <#{col.default.nsec}> vs <999999900>" - obj.datetime2_7.must_equal time, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <999999900>" - col.default_function.must_be_nil + _(col.default).must_equal time, "Nanoseconds were <#{col.default.nsec}> vs <999999900>" + _(obj.datetime2_7).must_equal time, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <999999900>" + _(col.default_function).must_be_nil type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::DateTime2 - type.limit.must_be_nil - type.precision.must_equal 7 - type.scale.must_be_nil + _(type).must_be_instance_of Type::DateTime2 + _(type.limit).must_be_nil + _(type.precision).must_equal 7 + _(type.scale).must_be_nil obj.save! - obj.must_equal obj.class.where(datetime2_7: time).first + _(obj).must_equal obj.class.where(datetime2_7: time).first # Can save 100 nanosecond precisoins and return again. time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456755, 1000) time2 = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456800, 1000) obj.datetime2_7 = time - obj.datetime2_7.must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" + _(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" obj.save! - obj.datetime2_7.must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" + _(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" obj.reload - obj.datetime2_7.must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" - obj.must_equal obj.class.where(datetime2_7: time).first - obj.must_equal obj.class.where(datetime2_7: time2).first + _(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <123456800>" + _(obj).must_equal obj.class.where(datetime2_7: time).first + _(obj).must_equal obj.class.where(datetime2_7: time2).first # Can save small fraction nanosecond precisoins and return again. time = Time.utc 2008, 6, 21, 13, 30, 0, Rational(15020, 1000) time2 = Time.utc 2008, 6, 21, 13, 30, 0, Rational(15000, 1000) obj.datetime2_7 = time - obj.datetime2_7.must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>" + _(obj.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>" obj.save! - obj.reload.datetime2_7.must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>" - obj.must_equal obj.class.where(datetime2_7: time).first - obj.must_equal obj.class.where(datetime2_7: time2).first + _(obj.reload.datetime2_7).must_equal time2, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <15000>" + _(obj).must_equal obj.class.where(datetime2_7: time).first + _(obj).must_equal obj.class.where(datetime2_7: time2).first # datetime2_3 time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(123456789, 1000) col = column('datetime2_3') - connection.lookup_cast_type_from_column(col).precision.must_equal 3 + _(connection.lookup_cast_type_from_column(col).precision).must_equal 3 obj.datetime2_3 = time - obj.datetime2_3.must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>" + _(obj.datetime2_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>" obj.save! ; obj.reload - obj.datetime2_3.must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>" - obj.must_equal obj.class.where(datetime2_3: time).first + _(obj.datetime2_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetime2_3.nsec}> vs <123000000>" + _(obj).must_equal obj.class.where(datetime2_3: time).first # datetime2_1 col = column('datetime2_1') - connection.lookup_cast_type_from_column(col).precision.must_equal 1 + _(connection.lookup_cast_type_from_column(col).precision).must_equal 1 obj.datetime2_1 = time - obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" + _(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" obj.save! ; obj.reload - obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" - obj.must_equal obj.class.where(datetime2_1: time).first + _(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" + _(obj).must_equal obj.class.where(datetime2_1: time).first # datetime2_0 col = column('datetime2_0') - connection.lookup_cast_type_from_column(col).precision.must_equal 0 + _(connection.lookup_cast_type_from_column(col).precision).must_equal 0 time = Time.utc 2016, 4, 19, 16, 45, 40, 771036 obj.datetime2_0 = time - obj.datetime2_0.must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>" + _(obj.datetime2_0).must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>" obj.save! ; obj.reload - obj.datetime2_0.must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>" - obj.must_equal obj.class.where(datetime2_0: time).first + _(obj.datetime2_0).must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>" + _(obj).must_equal obj.class.where(datetime2_0: time).first end it 'datetimeoffset' do skip 'datetimeoffset not supported in this protocal version' unless connection_dblib_73? col = column('datetimeoffset_7') - col.sql_type.must_equal 'datetimeoffset(7)' - col.type.must_equal :datetimeoffset - col.null.must_equal true - col.default.must_equal Time.new(1984, 01, 24, 04, 20, 00, -28800).change(nsec: 123456700), "Nanoseconds <#{col.default.nsec}> vs <123456700>" - obj.datetimeoffset_7.must_equal Time.new(1984, 01, 24, 04, 20, 00, -28800).change(nsec: 123456700), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <999999900>" - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::DateTimeOffset - type.limit.must_be_nil - type.precision.must_equal 7 - type.scale.must_be_nil + _(col.sql_type).must_equal 'datetimeoffset(7)' + _(col.type).must_equal :datetimeoffset + _(col.null).must_equal true + _(col.default).must_equal Time.new(1984, 01, 24, 04, 20, 00, -28800).change(nsec: 123456700), "Nanoseconds <#{col.default.nsec}> vs <123456700>" + _(obj.datetimeoffset_7).must_equal Time.new(1984, 01, 24, 04, 20, 00, -28800).change(nsec: 123456700), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <999999900>" + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::DateTimeOffset + _(type.limit).must_be_nil + _(type.precision).must_equal 7 + _(type.scale).must_be_nil # Can save 100 nanosecond precisoins and return again. obj.datetimeoffset_7 = Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456755) - obj.datetimeoffset_7.must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" + _(obj.datetimeoffset_7).must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" obj.save! - obj.datetimeoffset_7.must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" + _(obj.datetimeoffset_7).must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" obj.reload - obj.datetimeoffset_7.must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" + _(obj.datetimeoffset_7).must_equal Time.new(2010, 04, 01, 12, 34, 56, +18000).change(nsec: 123456800), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <123456800>" # Maintains the timezone time = ActiveSupport::TimeZone['America/Los_Angeles'].local 2010, 12, 31, 23, 59, 59, Rational(123456800, 1000) obj.datetimeoffset_7 = time - obj.datetimeoffset_7.must_equal time + _(obj.datetimeoffset_7).must_equal time obj.save! - obj.datetimeoffset_7.must_equal time - obj.reload.datetimeoffset_7.must_equal time + _(obj.datetimeoffset_7).must_equal time + _(obj.reload.datetimeoffset_7).must_equal time # With other precisions. time = ActiveSupport::TimeZone['America/Los_Angeles'].local 2010, 12, 31, 23, 59, 59, Rational(123456755, 1000) col = column('datetimeoffset_3') - connection.lookup_cast_type_from_column(col).precision.must_equal 3 + _(connection.lookup_cast_type_from_column(col).precision).must_equal 3 obj.datetimeoffset_3 = time - obj.datetimeoffset_3.must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>" + _(obj.datetimeoffset_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>" obj.save! - obj.datetimeoffset_3.must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>" + _(obj.datetimeoffset_3).must_equal time.change(nsec: 123000000), "Nanoseconds were <#{obj.datetimeoffset_3.nsec}> vs <123000000>" col = column('datetime2_1') - connection.lookup_cast_type_from_column(col).precision.must_equal 1 + _(connection.lookup_cast_type_from_column(col).precision).must_equal 1 obj.datetime2_1 = time - obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" + _(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" obj.save! - obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" + _(obj.datetime2_1).must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>" end it 'smalldatetime' do col = column('smalldatetime') - col.sql_type.must_equal 'smalldatetime' - col.type.must_equal :smalldatetime - col.null.must_equal true - col.default.must_equal Time.utc(1901, 01, 01, 15, 45, 00, 000) - obj.smalldatetime.must_equal Time.utc(1901, 01, 01, 15, 45, 00, 000) - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::SmallDateTime - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'smalldatetime' + _(col.type).must_equal :smalldatetime + _(col.null).must_equal true + _(col.default).must_equal Time.utc(1901, 01, 01, 15, 45, 00, 000) + _(obj.smalldatetime).must_equal Time.utc(1901, 01, 01, 15, 45, 00, 000) + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::SmallDateTime + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Will remove fractional seconds and return again. obj.smalldatetime = Time.utc(2078, 06, 05, 4, 20, 00, 3000) - obj.smalldatetime.must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.smalldatetime.usec}> vs <0>" + _(obj.smalldatetime).must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.smalldatetime.usec}> vs <0>" obj.save! - obj.smalldatetime.must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>" + _(obj.smalldatetime).must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>" obj.reload - obj.smalldatetime.must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>" + _(obj.smalldatetime).must_equal Time.utc(2078, 06, 05, 4, 20, 00, 0), "Microseconds were <#{obj.reload.smalldatetime.usec}> vs <0>" end it 'time(7)' do skip 'time() not supported in this protocal version' unless connection_dblib_73? col = column('time_7') - col.sql_type.must_equal 'time(7)' - col.type.must_equal :time - col.null.must_equal true - col.default.must_equal Time.utc(1900, 01, 01, 04, 20, 00, Rational(288321500, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <288321500>" - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Time - type.limit.must_be_nil - type.precision.must_equal 7 - type.scale.must_be_nil + _(col.sql_type).must_equal 'time(7)' + _(col.type).must_equal :time + _(col.null).must_equal true + _(col.default).must_equal Time.utc(1900, 01, 01, 04, 20, 00, Rational(288321500, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <288321500>" + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Time + _(type.limit).must_be_nil + _(type.precision).must_equal 7 + _(type.scale).must_be_nil # Time's #usec precision (low micro) obj.time_7 = Time.utc(2000, 01, 01, 15, 45, 00, 300) - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>" - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>" obj.save! ; obj.reload - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>" - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_7.usec}> vs <0>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_7.nsec}> vs <300>" # Time's #usec precision (high micro) obj.time_7 = Time.utc(2000, 01, 01, 15, 45, 00, 234567) - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>" obj.save! ; obj.reload - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_7.usec}> vs <234567>" # Time's #usec precision (high nano rounded) obj.time_7 = Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321545, 1000)) - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>" obj.save! ; obj.reload - obj.time_7.must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>" + _(obj.time_7).must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_7.nsec}> vs <288321500>" end it 'time(2)' do skip 'time() not supported in this protocal version' unless connection_dblib_73? col = column('time_2') - col.sql_type.must_equal 'time(2)' - col.type.must_equal :time - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Time - type.limit.must_be_nil - type.precision.must_equal 2 - type.scale.must_be_nil + _(col.sql_type).must_equal 'time(2)' + _(col.type).must_equal :time + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Time + _(type.limit).must_be_nil + _(type.precision).must_equal 2 + _(type.scale).must_be_nil # Always uses TinyTDS/Windows 2000-01-01 convention too. obj.time_2 = Time.utc(2015, 01, 10, 15, 45, 00, 0) - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0) + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0) obj.save! ; obj.reload - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0) + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0) # Time's #usec precision (barely in 2 precision equal to 0.03 seconds) obj.time_2 = Time.utc(2000, 01, 01, 15, 45, 00, 30000) - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>" + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>" obj.save! ; obj.reload - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>" + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 30000), "Microseconds were <#{obj.time_2.usec}> vs <30000>" # Time's #usec precision (below 2 precision) obj.time_2 = Time.utc(2000, 01, 01, 15, 45, 00, 4000) - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>" + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>" obj.save! ; obj.reload - obj.time_2.must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>" + _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>" end # Character Strings it 'char(10)' do col = column('char_10') - col.sql_type.must_equal 'char(10)' - col.type.must_equal :char - col.null.must_equal true - col.default.must_equal '1234567890' - obj.char_10.must_equal '1234567890' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Char - type.limit.must_equal 10 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'char(10)' + _(col.type).must_equal :char + _(col.null).must_equal true + _(col.default).must_equal '1234567890' + _(obj.char_10).must_equal '1234567890' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Char + _(type.limit).must_equal 10 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. obj.char_10 = '012345' - obj.char_10.strip.must_equal '012345' + _(obj.char_10.strip).must_equal '012345' obj.save! - obj.reload.char_10.strip.must_equal '012345' + _(obj.reload.char_10.strip).must_equal '012345' end it 'varchar(50)' do col = column('varchar_50') - col.sql_type.must_equal 'varchar(50)' - col.type.must_equal :varchar - col.null.must_equal true - col.default.must_equal 'test varchar_50' - obj.varchar_50.must_equal 'test varchar_50' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Varchar - type.limit.must_equal 50 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'varchar(50)' + _(col.type).must_equal :varchar + _(col.null).must_equal true + _(col.default).must_equal 'test varchar_50' + _(obj.varchar_50).must_equal 'test varchar_50' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Varchar + _(type.limit).must_equal 50 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :varchar_50, 'Hello World' end it 'varchar(max)' do col = column('varchar_max') - col.sql_type.must_equal 'varchar(max)' - col.type.must_equal :varchar_max - col.null.must_equal true - col.default.must_equal 'test varchar_max' - obj.varchar_max.must_equal 'test varchar_max' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::VarcharMax - type.limit.must_equal 2_147_483_647 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'varchar(max)' + _(col.type).must_equal :varchar_max + _(col.null).must_equal true + _(col.default).must_equal 'test varchar_max' + _(obj.varchar_max).must_equal 'test varchar_max' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::VarcharMax + _(type.limit).must_equal 2_147_483_647 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :varchar_max, 'Hello World' end it 'text' do col = column('text') - col.sql_type.must_equal 'text' - col.type.must_equal :text_basic - col.null.must_equal true - col.default.must_equal 'test text' - obj.text.must_equal 'test text' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Text - type.limit.must_equal 2_147_483_647 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'text' + _(col.type).must_equal :text_basic + _(col.null).must_equal true + _(col.default).must_equal 'test text' + _(obj.text).must_equal 'test text' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Text + _(type.limit).must_equal 2_147_483_647 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :text, 'Hello World' end @@ -618,71 +618,71 @@ def assert_obj_set_and_save(attribute, value) it 'nchar(10)' do col = column('nchar_10') - col.sql_type.must_equal 'nchar(10)' - col.type.must_equal :nchar - col.null.must_equal true - col.default.must_equal '12345678åå' - obj.nchar_10.must_equal '12345678åå' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::UnicodeChar - type.limit.must_equal 10 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'nchar(10)' + _(col.type).must_equal :nchar + _(col.null).must_equal true + _(col.default).must_equal '12345678åå' + _(obj.nchar_10).must_equal '12345678åå' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::UnicodeChar + _(type.limit).must_equal 10 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. obj.nchar_10 = "五六" - obj.nchar_10.strip.must_equal "五六" + _(obj.nchar_10.strip).must_equal "五六" obj.save! - obj.reload.nchar_10.strip.must_equal "五六" + _(obj.reload.nchar_10.strip).must_equal "五六" end it 'nvarchar(50)' do col = column('nvarchar_50') - col.sql_type.must_equal 'nvarchar(50)' - col.type.must_equal :string - col.null.must_equal true - col.default.must_equal 'test nvarchar_50 åå' - obj.nvarchar_50.must_equal 'test nvarchar_50 åå' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::UnicodeVarchar - type.limit.must_equal 50 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'nvarchar(50)' + _(col.type).must_equal :string + _(col.null).must_equal true + _(col.default).must_equal 'test nvarchar_50 åå' + _(obj.nvarchar_50).must_equal 'test nvarchar_50 åå' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::UnicodeVarchar + _(type.limit).must_equal 50 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :nvarchar_50, "一二34五六" end it 'nvarchar(max)' do col = column('nvarchar_max') - col.sql_type.must_equal 'nvarchar(max)' - col.type.must_equal :text - col.null.must_equal true - col.default.must_equal 'test nvarchar_max åå' - obj.nvarchar_max.must_equal 'test nvarchar_max åå' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::UnicodeVarcharMax - type.limit.must_equal 2_147_483_647 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'nvarchar(max)' + _(col.type).must_equal :text + _(col.null).must_equal true + _(col.default).must_equal 'test nvarchar_max åå' + _(obj.nvarchar_max).must_equal 'test nvarchar_max åå' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::UnicodeVarcharMax + _(type.limit).must_equal 2_147_483_647 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :nvarchar_max, "一二34五六" end it 'ntext' do col = column('ntext') - col.sql_type.must_equal 'ntext' - col.type.must_equal :ntext - col.null.must_equal true - col.default.must_equal 'test ntext åå' - obj.ntext.must_equal 'test ntext åå' - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::UnicodeText - type.limit.must_equal 2_147_483_647 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'ntext' + _(col.type).must_equal :ntext + _(col.null).must_equal true + _(col.default).must_equal 'test ntext åå' + _(obj.ntext).must_equal 'test ntext åå' + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::UnicodeText + _(type.limit).must_equal 2_147_483_647 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. assert_obj_set_and_save :ntext, "一二34五六" end @@ -694,60 +694,60 @@ def assert_obj_set_and_save(attribute, value) it 'binary(49)' do col = column('binary_49') - col.sql_type.must_equal 'binary(49)' - col.type.must_equal :binary_basic - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Binary - type.limit.must_equal 49 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'binary(49)' + _(col.type).must_equal :binary_basic + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Binary + _(type.limit).must_equal 49 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. - binary_data.encoding.must_equal Encoding::BINARY - binary_data.length.must_equal 49 + _(binary_data.encoding).must_equal Encoding::BINARY + _(binary_data.length).must_equal 49 obj.binary_49 = binary_data - obj.binary_49.must_equal binary_data + _(obj.binary_49).must_equal binary_data obj.save! - obj.reload.binary_49.must_equal binary_data + _(obj.reload.binary_49).must_equal binary_data end it 'varbinary(49)' do col = column('varbinary_49') - col.sql_type.must_equal 'varbinary(49)' - col.type.must_equal :varbinary - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Varbinary - type.limit.must_equal 49 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'varbinary(49)' + _(col.type).must_equal :varbinary + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Varbinary + _(type.limit).must_equal 49 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. binary_data_20 = binary_data.to(20) - binary_data_20.encoding.must_equal Encoding::BINARY + _(binary_data_20.encoding).must_equal Encoding::BINARY obj.varbinary_49 = binary_data_20 - obj.varbinary_49.must_equal binary_data_20 + _(obj.varbinary_49).must_equal binary_data_20 obj.save! - obj.reload.varbinary_49.must_equal binary_data_20 + _(obj.reload.varbinary_49).must_equal binary_data_20 end it 'varbinary(max)' do col = column('varbinary_max') - col.sql_type.must_equal 'varbinary(max)' - col.type.must_equal :binary - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::VarbinaryMax - type.limit.must_equal 2_147_483_647 - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'varbinary(max)' + _(col.type).must_equal :binary + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::VarbinaryMax + _(type.limit).must_equal 2_147_483_647 + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. - binary_data.encoding.must_equal Encoding::BINARY + _(binary_data.encoding).must_equal Encoding::BINARY assert_obj_set_and_save :varbinary_max, binary_data end @@ -755,43 +755,43 @@ def assert_obj_set_and_save(attribute, value) it 'uniqueidentifier' do col = column('uniqueidentifier') - col.sql_type.must_equal 'uniqueidentifier' - col.type.must_equal :uuid - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_equal 'newid()' - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Uuid - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'uniqueidentifier' + _(col.type).must_equal :uuid + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_equal 'newid()' + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Uuid + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic set and save. obj.uniqueidentifier = "this will not qualify as valid" - obj.uniqueidentifier.must_be_nil + _(obj.uniqueidentifier).must_be_nil obj.save! ; obj.reload - obj.uniqueidentifier.must_match Type::Uuid::ACCEPTABLE_UUID + _(obj.uniqueidentifier).must_match Type::Uuid::ACCEPTABLE_UUID obj.uniqueidentifier = "6F9619FF-8B86-D011-B42D-00C04FC964FF" - obj.uniqueidentifier.must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF" + _(obj.uniqueidentifier).must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF" obj.save! ; obj.reload - obj.uniqueidentifier.must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF" + _(obj.uniqueidentifier).must_equal "6F9619FF-8B86-D011-B42D-00C04FC964FF" end it 'timestamp' do col = column('timestamp') - col.sql_type.must_equal 'timestamp' - col.type.must_equal :ss_timestamp - col.null.must_equal true - col.default.must_be_nil - col.default_function.must_be_nil - type = connection.lookup_cast_type_from_column(col) - type.must_be_instance_of Type::Timestamp - type.limit.must_be_nil - type.precision.must_be_nil - type.scale.must_be_nil + _(col.sql_type).must_equal 'timestamp' + _(col.type).must_equal :ss_timestamp + _(col.null).must_equal true + _(col.default).must_be_nil + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Timestamp + _(type.limit).must_be_nil + _(type.precision).must_be_nil + _(type.scale).must_be_nil # Basic read. - obj.timestamp.must_be_nil + _(obj.timestamp).must_be_nil obj.save! ; obj.reload - obj.timestamp.must_match %r|\000| + _(obj.timestamp).must_match %r|\000| obj.timestamp # Can set another attribute obj.uniqueidentifier = "6F9619FF-8B86-D011-B42D-00C04FC964FF" @@ -801,7 +801,7 @@ def assert_obj_set_and_save(attribute, value) it 'does not mark object as changed after save' do obj.save! obj.attributes - obj.changed?.must_equal false + _(obj.changed?).must_equal false end end diff --git a/test/cases/connection_test_sqlserver.rb b/test/cases/connection_test_sqlserver.rb index 656c42fd4..e4c1ed55b 100644 --- a/test/cases/connection_test_sqlserver.rb +++ b/test/cases/connection_test_sqlserver.rb @@ -36,7 +36,7 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase describe 'Connection management' do it 'set spid on connect' do - ['Fixnum', 'Integer'].must_include connection.spid.class.name + _(['Fixnum', 'Integer']).must_include connection.spid.class.name end it 'reset spid on disconnect!' do @@ -46,7 +46,7 @@ class ConnectionTestSQLServer < ActiveRecord::TestCase it 'reset the connection' do connection.disconnect! - connection.raw_connection.must_be_nil + _(connection.raw_connection).must_be_nil end it 'be able to disconnect and reconnect at will' do diff --git a/test/cases/fetch_test_sqlserver.rb b/test/cases/fetch_test_sqlserver.rb index 787185d22..48e7ba2e5 100755 --- a/test/cases/fetch_test_sqlserver.rb +++ b/test/cases/fetch_test_sqlserver.rb @@ -36,11 +36,11 @@ class FetchTestSqlserver < ActiveRecord::TestCase it 'gauntlet' do Book.where(name:'Name-10').delete_all - Book.order(:name).limit(1).offset(1).map(&:name).must_equal ['Name-2'] - Book.order(:name).limit(2).offset(2).map(&:name).must_equal ['Name-3', 'Name-4'] - Book.order(:name).limit(2).offset(7).map(&:name).must_equal ['Name-8', 'Name-9'] - Book.order(:name).limit(3).offset(7).map(&:name).must_equal ['Name-8', 'Name-9'] - Book.order(:name).limit(3).offset(9).map(&:name).must_equal [] + _(Book.order(:name).limit(1).offset(1).map(&:name)).must_equal ['Name-2'] + _(Book.order(:name).limit(2).offset(2).map(&:name)).must_equal ['Name-3', 'Name-4'] + _(Book.order(:name).limit(2).offset(7).map(&:name)).must_equal ['Name-8', 'Name-9'] + _(Book.order(:name).limit(3).offset(7).map(&:name)).must_equal ['Name-8', 'Name-9'] + _(Book.order(:name).limit(3).offset(9).map(&:name)).must_equal [] end end diff --git a/test/cases/json_test_sqlserver.rb b/test/cases/json_test_sqlserver.rb index 37168e785..664c8327c 100644 --- a/test/cases/json_test_sqlserver.rb +++ b/test/cases/json_test_sqlserver.rb @@ -12,20 +12,20 @@ class JsonTestSQLServer < ActiveRecord::TestCase end it 'can return and save JSON data' do - SSTestDatatypeMigrationJson.find(@o1.id).json_col.must_equal({ 'a' => 'a', 'b' => 'b', 'c' => 'c' }) + _(SSTestDatatypeMigrationJson.find(@o1.id).json_col).must_equal({ 'a' => 'a', 'b' => 'b', 'c' => 'c' }) @o1.json_col = { 'a' => 'a' } - @o1.json_col.must_equal({ 'a' => 'a' }) + _(@o1.json_col).must_equal({ 'a' => 'a' }) @o1.save! - @o1.reload.json_col.must_equal({ 'a' => 'a' }) + _(@o1.reload.json_col).must_equal({ 'a' => 'a' }) end it 'can use ISJSON function' do - SSTestDatatypeMigrationJson.where('ISJSON(json_col) > 0').count.must_equal 4 - SSTestDatatypeMigrationJson.where('ISJSON(json_col) IS NULL').count.must_equal 1 + _(SSTestDatatypeMigrationJson.where('ISJSON(json_col) > 0').count).must_equal 4 + _(SSTestDatatypeMigrationJson.where('ISJSON(json_col) IS NULL').count).must_equal 1 end it 'can use JSON_VALUE function' do - SSTestDatatypeMigrationJson.where("JSON_VALUE(json_col, '$.b') = 'b'").count.must_equal 2 + _(SSTestDatatypeMigrationJson.where("JSON_VALUE(json_col, '$.b') = 'b'").count).must_equal 2 end end diff --git a/test/cases/migration_test_sqlserver.rb b/test/cases/migration_test_sqlserver.rb index fb059ddee..088024df3 100644 --- a/test/cases/migration_test_sqlserver.rb +++ b/test/cases/migration_test_sqlserver.rb @@ -24,8 +24,8 @@ class MigrationTestSQLServer < ActiveRecord::TestCase rescue Exception => e assert_match %r|this and all later migrations canceled|, e.message end - connection.tables.wont_include @trans_test_table1 - connection.tables.wont_include @trans_test_table2 + _(connection.tables).wont_include @trans_test_table1 + _(connection.tables).wont_include @trans_test_table2 end end diff --git a/test/cases/pessimistic_locking_test_sqlserver.rb b/test/cases/pessimistic_locking_test_sqlserver.rb index 96649e087..0e3e44fd4 100644 --- a/test/cases/pessimistic_locking_test_sqlserver.rb +++ b/test/cases/pessimistic_locking_test_sqlserver.rb @@ -13,7 +13,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase it 'uses with updlock by default' do assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\)| do - Person.lock(true).to_a.must_equal Person.all.to_a + _(Person.lock(true).to_a).must_equal Person.all.to_a end end @@ -22,7 +22,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase it 'lock with simple find' do assert_nothing_raised do Person.transaction do - Person.lock(true).find(1).must_equal Person.find(1) + _(Person.lock(true).find(1)).must_equal Person.find(1) end end end @@ -31,7 +31,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase assert_nothing_raised do Person.transaction do Person.lock(true).scoping do - Person.find(1).must_equal Person.find(1) + _(Person.find(1)).must_equal Person.find(1) end end end @@ -41,7 +41,7 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase assert_nothing_raised do Person.transaction do person = Person.lock(true).includes(:readers).find(1) - person.must_equal Person.find(1) + _(person).must_equal Person.find(1) end end end @@ -94,11 +94,11 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase loader_sql = /SELECT.*FROM \[people\] WITH\(UPDLOCK\).*WHERE \[people\]\.\[id\] IN/ assert_sql(eager_ids_sql, loader_sql) do people = Person.lock(true).limit(5).offset(10).includes(:readers).references(:readers).to_a - people[0].first_name.must_equal 'Thing_10' - people[1].first_name.must_equal 'Thing_11' - people[2].first_name.must_equal 'Thing_12' - people[3].first_name.must_equal 'Thing_13' - people[4].first_name.must_equal 'Thing_14' + _(people[0].first_name).must_equal 'Thing_10' + _(people[1].first_name).must_equal 'Thing_11' + _(people[2].first_name).must_equal 'Thing_12' + _(people[3].first_name).must_equal 'Thing_13' + _(people[4].first_name).must_equal 'Thing_14' end end diff --git a/test/cases/rake_test_sqlserver.rb b/test/cases/rake_test_sqlserver.rb index 09b2bf664..366ece3e4 100644 --- a/test/cases/rake_test_sqlserver.rb +++ b/test/cases/rake_test_sqlserver.rb @@ -43,23 +43,23 @@ class SQLServerRakeCreateTest < SQLServerRakeTest it 'establishes connection to database after create ' do quietly { db_tasks.create configuration } - connection.current_database.must_equal(new_database) + _(connection.current_database).must_equal(new_database) end it 'creates database with default collation' do quietly { db_tasks.create configuration } - connection.collation.must_equal 'SQL_Latin1_General_CP1_CI_AS' + _(connection.collation).must_equal 'SQL_Latin1_General_CP1_CI_AS' end it 'creates database with given collation' do quietly { db_tasks.create configuration.merge('collation' => 'Latin1_General_CI_AS') } - connection.collation.must_equal 'Latin1_General_CI_AS' + _(connection.collation).must_equal 'Latin1_General_CI_AS' end it 'prints error message when database exists' do quietly { db_tasks.create configuration } message = capture(:stderr) { db_tasks.create configuration } - message.must_match %r{activerecord_unittest_tasks.*already exists} + _(message).must_match %r{activerecord_unittest_tasks.*already exists} end end @@ -73,12 +73,12 @@ class SQLServerRakeDropTest < SQLServerRakeTest db_tasks.create configuration db_tasks.drop configuration end - connection.current_database.must_equal 'master' + _(connection.current_database).must_equal 'master' end it 'prints error message when database does not exist' do message = capture(:stderr) { db_tasks.drop configuration.merge('database' => 'doesnotexist') } - message.must_match %r{'doesnotexist' does not exist} + _(message).must_match %r{'doesnotexist' does not exist} end end @@ -94,11 +94,11 @@ class SQLServerRakePurgeTest < SQLServerRakeTest end it 'clears active connections, drops database, and recreates with established connection' do - connection.current_database.must_equal(new_database) - connection.tables.must_include 'users' + _(connection.current_database).must_equal(new_database) + _(connection.tables).must_include 'users' quietly { db_tasks.purge(configuration) } - connection.current_database.must_equal(new_database) - connection.tables.wont_include 'users' + _(connection.current_database).must_equal(new_database) + _(connection.tables).wont_include 'users' end end @@ -110,7 +110,7 @@ class SQLServerRakeCharsetTest < SQLServerRakeTest end it 'retrieves charset' do - db_tasks.charset(configuration).must_equal 'iso_1' + _(db_tasks.charset(configuration)).must_equal 'iso_1' end end @@ -122,7 +122,7 @@ class SQLServerRakeCollationTest < SQLServerRakeTest end it 'retrieves collation' do - db_tasks.collation(configuration).must_equal 'SQL_Latin1_General_CP1_CI_AS' + _(db_tasks.collation(configuration)).must_equal 'SQL_Latin1_General_CP1_CI_AS' end end @@ -149,21 +149,21 @@ class SQLServerRakeStructureDumpLoadTest < SQLServerRakeTest it 'dumps structure and accounts for defncopy oddities' do skip 'debug defncopy on windows later' if host_windows? quietly { db_tasks.structure_dump configuration, filename } - filedata.wont_match %r{\AUSE.*\z} - filedata.wont_match %r{\AGO.*\z} - filedata.must_match %r{email\s+nvarchar\(4000\)} - filedata.must_match %r{background1\s+nvarchar\(max\)} - filedata.must_match %r{background2\s+text\s+} + _(filedata).wont_match %r{\AUSE.*\z} + _(filedata).wont_match %r{\AGO.*\z} + _(filedata).must_match %r{email\s+nvarchar\(4000\)} + _(filedata).must_match %r{background1\s+nvarchar\(max\)} + _(filedata).must_match %r{background2\s+text\s+} end it 'can load dumped structure' do skip 'debug defncopy on windows later' if host_windows? quietly { db_tasks.structure_dump configuration, filename } - filedata.must_match %r{CREATE TABLE dbo\.users} + _(filedata).must_match %r{CREATE TABLE dbo\.users} db_tasks.purge(configuration) - connection.tables.wont_include 'users' + _(connection.tables).wont_include 'users' db_tasks.load_schema configuration, :sql, filename - connection.tables.must_include 'users' + _(connection.tables).must_include 'users' end end diff --git a/test/cases/schema_dumper_test_sqlserver.rb b/test/cases/schema_dumper_test_sqlserver.rb index 950c85b62..3da17ca1c 100644 --- a/test/cases/schema_dumper_test_sqlserver.rb +++ b/test/cases/schema_dumper_test_sqlserver.rb @@ -58,18 +58,18 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase columns = SSTestDatatypeMigration.columns_hash generate_schema_for_table 'sst_datatypes_migration' # Simple Rails conventions - columns['integer_col'].sql_type.must_equal 'int(4)' - columns['bigint_col'].sql_type.must_equal 'bigint(8)' - columns['boolean_col'].sql_type.must_equal 'bit' - columns['decimal_col'].sql_type.must_equal 'decimal(18,0)' - columns['float_col'].sql_type.must_equal 'float' - columns['string_col'].sql_type.must_equal 'nvarchar(4000)' - columns['text_col'].sql_type.must_equal 'nvarchar(max)' - columns['datetime_col'].sql_type.must_equal 'datetime' - columns['timestamp_col'].sql_type.must_equal 'datetime' - columns['time_col'].sql_type.must_equal 'time(7)' - columns['date_col'].sql_type.must_equal 'date' - columns['binary_col'].sql_type.must_equal 'varbinary(max)' + _(columns['integer_col'].sql_type).must_equal 'int(4)' + _(columns['bigint_col'].sql_type).must_equal 'bigint(8)' + _(columns['boolean_col'].sql_type).must_equal 'bit' + _(columns['decimal_col'].sql_type).must_equal 'decimal(18,0)' + _(columns['float_col'].sql_type).must_equal 'float' + _(columns['string_col'].sql_type).must_equal 'nvarchar(4000)' + _(columns['text_col'].sql_type).must_equal 'nvarchar(max)' + _(columns['datetime_col'].sql_type).must_equal 'datetime' + _(columns['timestamp_col'].sql_type).must_equal 'datetime' + _(columns['time_col'].sql_type).must_equal 'time(7)' + _(columns['date_col'].sql_type).must_equal 'date' + _(columns['binary_col'].sql_type).must_equal 'varbinary(max)' assert_line :integer_col, type: 'integer', limit: nil, precision: nil, scale: nil, default: nil assert_line :bigint_col, type: 'bigint', limit: nil, precision: nil, scale: nil, default: nil assert_line :boolean_col, type: 'boolean', limit: nil, precision: nil, scale: nil, default: nil @@ -83,22 +83,22 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase assert_line :date_col, type: 'date', limit: nil, precision: nil, scale: nil, default: nil assert_line :binary_col, type: 'binary', limit: nil, precision: nil, scale: nil, default: nil # Our type methods. - columns['real_col'].sql_type.must_equal 'real' - columns['money_col'].sql_type.must_equal 'money' - columns['smalldatetime_col'].sql_type.must_equal 'smalldatetime' - columns['datetime2_col'].sql_type.must_equal 'datetime2(7)' - columns['datetimeoffset'].sql_type.must_equal 'datetimeoffset(7)' - columns['smallmoney_col'].sql_type.must_equal 'smallmoney' - columns['char_col'].sql_type.must_equal 'char(1)' - columns['varchar_col'].sql_type.must_equal 'varchar(8000)' - columns['text_basic_col'].sql_type.must_equal 'text' - columns['nchar_col'].sql_type.must_equal 'nchar(1)' - columns['ntext_col'].sql_type.must_equal 'ntext' - columns['binary_basic_col'].sql_type.must_equal 'binary(1)' - columns['varbinary_col'].sql_type.must_equal 'varbinary(8000)' - columns['uuid_col'].sql_type.must_equal 'uniqueidentifier' - columns['sstimestamp_col'].sql_type.must_equal 'timestamp' - columns['json_col'].sql_type.must_equal 'nvarchar(max)' + _(columns['real_col'].sql_type).must_equal 'real' + _(columns['money_col'].sql_type).must_equal 'money' + _(columns['smalldatetime_col'].sql_type).must_equal 'smalldatetime' + _(columns['datetime2_col'].sql_type).must_equal 'datetime2(7)' + _(columns['datetimeoffset'].sql_type).must_equal 'datetimeoffset(7)' + _(columns['smallmoney_col'].sql_type).must_equal 'smallmoney' + _(columns['char_col'].sql_type).must_equal 'char(1)' + _(columns['varchar_col'].sql_type).must_equal 'varchar(8000)' + _(columns['text_basic_col'].sql_type).must_equal 'text' + _(columns['nchar_col'].sql_type).must_equal 'nchar(1)' + _(columns['ntext_col'].sql_type).must_equal 'ntext' + _(columns['binary_basic_col'].sql_type).must_equal 'binary(1)' + _(columns['varbinary_col'].sql_type).must_equal 'varbinary(8000)' + _(columns['uuid_col'].sql_type).must_equal 'uniqueidentifier' + _(columns['sstimestamp_col'].sql_type).must_equal 'timestamp' + _(columns['json_col'].sql_type).must_equal 'nvarchar(max)' assert_line :real_col, type: 'real', limit: nil, precision: nil, scale: nil, default: nil assert_line :money_col, type: 'money', limit: nil, precision: 19, scale: 4, default: nil assert_line :smalldatetime_col, type: 'smalldatetime', limit: nil, precision: nil, scale: nil, default: nil @@ -129,7 +129,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase it 'no id with model driven primary key' do output = generate_schema_for_table 'sst_no_pk_data' - output.must_match %r{create_table "sst_no_pk_data".*id:\sfalse.*do} + _(output).must_match %r{create_table "sst_no_pk_data".*id:\sfalse.*do} assert_line :name, type: 'string', limit: nil, default: nil, collation: nil end @@ -165,15 +165,15 @@ def assert_line(column_name, options={}) expected = options[key] message = "#{key.to_s.titleize} of #{expected.inspect} not found in:\n#{line}" if expected.nil? - actual.must_be_nil message + _(actual).must_be_nil message elsif expected.is_a?(Array) actual.must_include expected, message elsif expected.is_a?(Float) - actual.must_be_close_to expected, 0.001 + _(actual).must_be_close_to expected, 0.001 elsif expected.is_a?(Proc) - actual.call.must_equal(expected.call) + _(actual.call).must_equal(expected.call) else - actual.must_equal expected, message + _(actual).must_equal expected, message end end end diff --git a/test/cases/schema_test_sqlserver.rb b/test/cases/schema_test_sqlserver.rb index a2887ca2e..5986b5b06 100644 --- a/test/cases/schema_test_sqlserver.rb +++ b/test/cases/schema_test_sqlserver.rb @@ -5,7 +5,7 @@ class SchemaTestSQLServer < ActiveRecord::TestCase describe 'When table is dbo schema' do it 'find primary key for tables with odd schema' do - connection.primary_key('sst_natural_pk_data').must_equal 'legacy_id' + _(connection.primary_key('sst_natural_pk_data')).must_equal 'legacy_id' end end @@ -18,7 +18,7 @@ class SchemaTestSQLServer < ActiveRecord::TestCase end it 'find primary key for tables with odd schema' do - connection.primary_key('test.sst_schema_natural_id').must_equal 'legacy_id' + _(connection.primary_key('test.sst_schema_natural_id')).must_equal 'legacy_id' end it "have only one identity column" do diff --git a/test/cases/showplan_test_sqlserver.rb b/test/cases/showplan_test_sqlserver.rb index 9e4afb3cd..848f6f151 100644 --- a/test/cases/showplan_test_sqlserver.rb +++ b/test/cases/showplan_test_sqlserver.rb @@ -9,33 +9,33 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase it 'from simple statement' do plan = Car.where(id: 1).explain - plan.must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] = 1" - plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' + _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id] = 1" + _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' end it 'from multiline statement' do plan = Car.where("\n id = 1 \n").explain - plan.must_include "SELECT [cars].* FROM [cars] WHERE (\n id = 1 \n)" - plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' + _(plan).must_include "SELECT [cars].* FROM [cars] WHERE (\n id = 1 \n)" + _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' end it 'from prepared statement' do plan = Car.where(name: ',').limit(1).explain - plan.must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]" - plan.must_include "TOP EXPRESSION", 'make sure we do not showplan the sp_executesql' - plan.must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql' + _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name]" + _(plan).must_include "TOP EXPRESSION", 'make sure we do not showplan the sp_executesql' + _(plan).must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql' end it 'from array condition using index' do plan = Car.where(id: [1, 2]).explain - plan.must_include " SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)" - plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' + _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[id] IN (1, 2)" + _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' end it 'from array condition' do plan = Car.where(name: ['honda', 'zyke']).explain - plan.must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')" - plan.must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql' + _(plan).must_include " SELECT [cars].* FROM [cars] WHERE [cars].[name] IN (N'honda', N'zyke')" + _(plan).must_include "Clustered Index Scan", 'make sure we do not showplan the sp_executesql' end end @@ -45,8 +45,8 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase it 'use simple table printer' do with_showplan_option('SHOWPLAN_TEXT') do plan = Car.where(id: 1).explain - plan.must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]" - plan.must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' + _(plan).must_include "SELECT [cars].* FROM [cars] WHERE [cars].[id]" + _(plan).must_include "Clustered Index Seek", 'make sure we do not showplan the sp_executesql' end end @@ -57,7 +57,7 @@ class ShowplanTestSQLServer < ActiveRecord::TestCase it 'show formatted xml' do with_showplan_option('SHOWPLAN_XML') do plan = Car.where(id: 1).explain - plan.must_include 'ShowPlanXML' + _(plan).must_include 'ShowPlanXML' end end diff --git a/test/cases/specific_schema_test_sqlserver.rb b/test/cases/specific_schema_test_sqlserver.rb index 4f106385d..9e0659227 100644 --- a/test/cases/specific_schema_test_sqlserver.rb +++ b/test/cases/specific_schema_test_sqlserver.rb @@ -11,8 +11,8 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase it 'models can use tinyint pk tables' do obj = SSTestTinyintPk.create! name: '1' - ['Fixnum', 'Integer'].must_include obj.id.class.name - SSTestTinyintPk.find(obj.id).must_equal obj + _(['Fixnum', 'Integer']).must_include obj.id.class.name + _(SSTestTinyintPk.find(obj.id)).must_equal obj end it 'be able to complex count tables with no primary key' do @@ -58,17 +58,17 @@ class SpecificSchemaTestSQLServer < ActiveRecord::TestCase it 'default objects work' do obj = SSTestObjectDefault.create! name: 'MetaSkills' - obj.date.must_be_nil 'since this is set on insert' - obj.reload.date.must_be_instance_of Date + _(obj.date).must_be_nil 'since this is set on insert' + _(obj.reload.date).must_be_instance_of Date end it 'allows datetime2 as timestamps' do - SSTestBooking.columns_hash['created_at'].sql_type.must_equal 'datetime2(7)' - SSTestBooking.columns_hash['updated_at'].sql_type.must_equal 'datetime2(7)' + _(SSTestBooking.columns_hash['created_at'].sql_type).must_equal 'datetime2(7)' + _(SSTestBooking.columns_hash['updated_at'].sql_type).must_equal 'datetime2(7)' obj1 = SSTestBooking.new name: 'test1' obj1.save! - obj1.created_at.must_be_instance_of Time - obj1.updated_at.must_be_instance_of Time + _(obj1.created_at).must_be_instance_of Time + _(obj1.updated_at).must_be_instance_of Time end # Natural primary keys. @@ -124,10 +124,10 @@ def quoted_id o = SSTestDatatypeMigration.create! o.varchar_col = "O'Reilly" o.save! - o.reload.varchar_col.must_equal "O'Reilly" + _(o.reload.varchar_col).must_equal "O'Reilly" o.varchar_col = nil o.save! - o.reload.varchar_col.must_be_nil + _(o.reload.varchar_col).must_be_nil end # With column names that have spaces @@ -156,7 +156,7 @@ def quoted_id it 'returns a new id via connection newid_function' do acceptable_uuid = ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID db_uuid = ActiveRecord::Base.connection.newid_function - db_uuid.must_match(acceptable_uuid) + _(db_uuid).must_match(acceptable_uuid) end # with similar table definition in two schemas diff --git a/test/cases/transaction_test_sqlserver.rb b/test/cases/transaction_test_sqlserver.rb index e16a63a53..bca3c071e 100644 --- a/test/cases/transaction_test_sqlserver.rb +++ b/test/cases/transaction_test_sqlserver.rb @@ -34,22 +34,22 @@ class TransactionTestSQLServer < ActiveRecord::TestCase it 'can use an isolation level and reverts back to starting isolation level' do in_level = nil begin_level = connection.user_options_isolation_level - begin_level.must_match %r{read committed}i + _(begin_level).must_match %r{read committed}i Ship.transaction(isolation: :serializable) do Ship.create! name: 'Black Pearl' in_level = connection.user_options_isolation_level end after_level = connection.user_options_isolation_level - in_level.must_match %r{serializable}i - after_level.must_match %r{read committed}i + _(in_level).must_match %r{serializable}i + _(after_level).must_match %r{read committed}i end it 'can use an isolation level and reverts back to starting isolation level under exceptions' do - connection.user_options_isolation_level.must_match %r{read committed}i - lambda { + _(connection.user_options_isolation_level).must_match %r{read committed}i + _(lambda { Ship.transaction(isolation: :serializable) { Ship.create! } - }.must_raise(ActiveRecord::RecordInvalid) - connection.user_options_isolation_level.must_match %r{read committed}i + }).must_raise(ActiveRecord::RecordInvalid) + _(connection.user_options_isolation_level).must_match %r{read committed}i end describe 'when READ_COMMITTED_SNAPSHOT is set' do @@ -64,7 +64,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase end it 'should use READ COMMITTED as an isolation level' do - connection.user_options_isolation_level.must_match "read committed snapshot" + _(connection.user_options_isolation_level).must_match "read committed snapshot" Ship.transaction(isolation: :serializable) do Ship.create! name: 'Black Pearl' @@ -73,7 +73,7 @@ class TransactionTestSQLServer < ActiveRecord::TestCase # We're actually testing that the isolation level was correctly reset to # "READ COMMITTED", and that no exception was raised (it's reported back # by SQL Server as "read committed snapshot"). - connection.user_options_isolation_level.must_match "read committed snapshot" + _(connection.user_options_isolation_level).must_match "read committed snapshot" end end diff --git a/test/cases/trigger_test_sqlserver.rb b/test/cases/trigger_test_sqlserver.rb index 2c77546dc..c762c709e 100644 --- a/test/cases/trigger_test_sqlserver.rb +++ b/test/cases/trigger_test_sqlserver.rb @@ -12,19 +12,19 @@ class SQLServerTriggerTest < ActiveRecord::TestCase exclude_output_inserted_table_names['sst_table_with_trigger'] = true assert SSTestTriggerHistory.all.empty? obj = SSTestTrigger.create! event_name: 'test trigger' - ['Fixnum', 'Integer'].must_include obj.id.class.name - obj.event_name.must_equal 'test trigger' - obj.id.must_be :present? - obj.id.to_s.must_equal SSTestTriggerHistory.first.id_source + _(['Fixnum', 'Integer']).must_include obj.id.class.name + _(obj.event_name).must_equal 'test trigger' + _(obj.id).must_be :present? + _(obj.id.to_s).must_equal SSTestTriggerHistory.first.id_source end it 'can insert into a table with output inserted - with a uniqueidentifier value' do exclude_output_inserted_table_names['sst_table_with_uuid_trigger'] = 'uniqueidentifier' assert SSTestTriggerHistory.all.empty? obj = SSTestTriggerUuid.create! event_name: 'test uuid trigger' - obj.id.class.name.must_equal 'String' - obj.event_name.must_equal 'test uuid trigger' - obj.id.must_be :present? - obj.id.to_s.must_equal SSTestTriggerHistory.first.id_source + _(obj.id.class.name).must_equal 'String' + _(obj.event_name).must_equal 'test uuid trigger' + _(obj.id).must_be :present? + _(obj.id.to_s).must_equal SSTestTriggerHistory.first.id_source end end diff --git a/test/cases/utils_test_sqlserver.rb b/test/cases/utils_test_sqlserver.rb index 492fdabf0..c64939384 100644 --- a/test/cases/utils_test_sqlserver.rb +++ b/test/cases/utils_test_sqlserver.rb @@ -3,15 +3,15 @@ class UtilsTestSQLServer < ActiveRecord::TestCase it '.quote_string' do - SQLServer::Utils.quote_string("I'll store this in C:\\Users").must_equal "I''ll store this in C:\\Users" + _(SQLServer::Utils.quote_string("I'll store this in C:\\Users")).must_equal "I''ll store this in C:\\Users" end it '.unquote_string' do - SQLServer::Utils.unquote_string("I''ll store this in C:\\Users").must_equal "I'll store this in C:\\Users" + _(SQLServer::Utils.unquote_string("I''ll store this in C:\\Users")).must_equal "I'll store this in C:\\Users" end it '.quoted_raw' do - SQLServer::Utils.quoted_raw("some.Name").must_equal "[some.Name]" + _(SQLServer::Utils.quoted_raw("some.Name")).must_equal "[some.Name]" end describe '.extract_identifiers constructor and thus SQLServer::Utils::Name value object' do @@ -47,8 +47,8 @@ class UtilsTestSQLServer < ActiveRecord::TestCase it 'extracts and returns #object identifier unquoted by default or quoted as needed' do valid_names.each do |n| name = extract_identifiers(n) - name.object.must_equal 'object', "With #{n.inspect} for #object" - name.object_quoted.must_equal '[object]', "With #{n.inspect} for #object_quoted" + _(name.object).must_equal 'object', "With #{n.inspect} for #object" + _(name.object_quoted).must_equal '[object]', "With #{n.inspect} for #object_quoted" end end @@ -58,64 +58,64 @@ class UtilsTestSQLServer < ActiveRecord::TestCase present, blank = send(:"#{part}_names") present.each do |n| name = extract_identifiers(n) - name.send(:"#{part}").must_equal "#{part}", "With #{n.inspect} for ##{part} method" - name.send(:"#{part}_quoted").must_equal "[#{part}]", "With #{n.inspect} for ##{part}_quoted method" + _(name.send(:"#{part}")).must_equal "#{part}", "With #{n.inspect} for ##{part} method" + _(name.send(:"#{part}_quoted")).must_equal "[#{part}]", "With #{n.inspect} for ##{part}_quoted method" end blank.each do |n| name = extract_identifiers(n) - name.send(:"#{part}").must_be_nil "With #{n.inspect} for ##{part} method" - name.send(:"#{part}_quoted").must_be_nil "With #{n.inspect} for ##{part}_quoted method" + _(name.send(:"#{part}")).must_be_nil "With #{n.inspect} for ##{part} method" + _(name.send(:"#{part}_quoted")).must_be_nil "With #{n.inspect} for ##{part}_quoted method" end end end it 'does not blow up on nil or blank string name' do - extract_identifiers(nil).object.must_be_nil - extract_identifiers(' ').object.must_be_nil + _(extract_identifiers(nil).object).must_be_nil + _(extract_identifiers(' ').object).must_be_nil end it 'has a #quoted that returns a fully quoted name with all identifiers as orginially passed in' do - extract_identifiers('object').quoted.must_equal '[object]' - extract_identifiers('server.database..object').quoted.must_equal '[server].[database]..[object]' - extract_identifiers('[server]...[object]').quoted.must_equal '[server]...[object]' + _(extract_identifiers('object').quoted).must_equal '[object]' + _(extract_identifiers('server.database..object').quoted).must_equal '[server].[database]..[object]' + _(extract_identifiers('[server]...[object]').quoted).must_equal '[server]...[object]' end it 'can take a symbol argument' do - extract_identifiers(:object).object.must_equal 'object' + _(extract_identifiers(:object).object).must_equal 'object' end it 'allows identifiers with periods to work' do - extract_identifiers('[obj.name]').quoted.must_equal '[obj.name]' - extract_identifiers('[obj.name].[foo]').quoted.must_equal '[obj.name].[foo]' + _(extract_identifiers('[obj.name]').quoted).must_equal '[obj.name]' + _(extract_identifiers('[obj.name].[foo]').quoted).must_equal '[obj.name].[foo]' end it 'should indicate if a name is fully qualitified' do - extract_identifiers('object').fully_qualified?.must_equal false - extract_identifiers('schema.object').fully_qualified?.must_equal false - extract_identifiers('database.schema.object').fully_qualified?.must_equal false - extract_identifiers('database.object').fully_qualified?.must_equal false - extract_identifiers('server...object').fully_qualified?.must_equal false - extract_identifiers('server.database..object').fully_qualified?.must_equal false - extract_identifiers('server.database.schema.object').fully_qualified?.must_equal true - extract_identifiers('server.database.schema.').fully_qualified?.must_equal true - extract_identifiers('[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[schema].[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[database].[schema].[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[database].[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[server.name]...[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[server.name].[database]..[obj.name]').fully_qualified?.must_equal false - extract_identifiers('[server.name].[database].[schema].[obj.name]').fully_qualified?.must_equal true - extract_identifiers('[server.name].[database].[schema].').fully_qualified?.must_equal true + _(extract_identifiers('object').fully_qualified?).must_equal false + _(extract_identifiers('schema.object').fully_qualified?).must_equal false + _(extract_identifiers('database.schema.object').fully_qualified?).must_equal false + _(extract_identifiers('database.object').fully_qualified?).must_equal false + _(extract_identifiers('server...object').fully_qualified?).must_equal false + _(extract_identifiers('server.database..object').fully_qualified?).must_equal false + _(extract_identifiers('server.database.schema.object').fully_qualified?).must_equal true + _(extract_identifiers('server.database.schema.').fully_qualified?).must_equal true + _(extract_identifiers('[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[schema].[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[database].[schema].[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[database].[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[server.name]...[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[server.name].[database]..[obj.name]').fully_qualified?).must_equal false + _(extract_identifiers('[server.name].[database].[schema].[obj.name]').fully_qualified?).must_equal true + _(extract_identifiers('[server.name].[database].[schema].').fully_qualified?).must_equal true end it 'can return fully qualified quoted table name' do name = extract_identifiers('[my.server].db.schema.') - name.fully_qualified_database_quoted.must_equal '[my.server].[db]' + _(name.fully_qualified_database_quoted).must_equal '[my.server].[db]' name = extract_identifiers('[server.name].[database].[schema].[object]') - name.fully_qualified_database_quoted.must_equal '[server.name].[database]' + _(name.fully_qualified_database_quoted).must_equal '[server.name].[database]' name = extract_identifiers('server.database.schema.object') - name.fully_qualified_database_quoted.must_equal '[server].[database]' + _(name.fully_qualified_database_quoted).must_equal '[server].[database]' end end diff --git a/test/cases/uuid_test_sqlserver.rb b/test/cases/uuid_test_sqlserver.rb index cf99f0dd7..c97319230 100644 --- a/test/cases/uuid_test_sqlserver.rb +++ b/test/cases/uuid_test_sqlserver.rb @@ -6,24 +6,24 @@ class SQLServerUuidTest < ActiveRecord::TestCase let(:acceptable_uuid) { ActiveRecord::ConnectionAdapters::SQLServer::Type::Uuid::ACCEPTABLE_UUID } it 'has a uuid primary key' do - SSTestUuid.columns_hash['id'].type.must_equal :uuid + _(SSTestUuid.columns_hash['id'].type).must_equal :uuid assert SSTestUuid.primary_key end it 'can create with a new pk' do obj = SSTestUuid.create! - obj.id.must_be :present? - obj.id.must_match acceptable_uuid + _(obj.id).must_be :present? + _(obj.id).must_match acceptable_uuid end it 'can create other uuid column on reload' do obj = SSTestUuid.create! obj.reload - obj.other_uuid.must_match acceptable_uuid + _(obj.other_uuid).must_match acceptable_uuid end it 'can find uuid pk via connection' do - connection.primary_key(SSTestUuid.table_name).must_equal 'id' + _(connection.primary_key(SSTestUuid.table_name)).must_equal 'id' end it 'changing column default' do @@ -31,17 +31,17 @@ class SQLServerUuidTest < ActiveRecord::TestCase connection.add_column table_name, :thingy, :uuid, null: false, default: "NEWSEQUENTIALID()" SSTestUuid.reset_column_information column = SSTestUuid.columns_hash['thingy'] - column.default_function.must_equal "newsequentialid()" + _(column.default_function).must_equal "newsequentialid()" # Now to a different function. connection.change_column table_name, :thingy, :uuid, null: false, default: "NEWID()" SSTestUuid.reset_column_information column = SSTestUuid.columns_hash['thingy'] - column.default_function.must_equal "newid()" + _(column.default_function).must_equal "newid()" end it 'can insert even when use_output_inserted to false ' do obj = with_use_output_inserted_disabled { SSTestUuid.create!(name: "😢") } - obj.id.must_be :nil? + _(obj.id).must_be :nil? end end From c6308c271f931eb0b62c7449992e45199d41fa84 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 25 Feb 2020 11:29:27 +0000 Subject: [PATCH 3/9] Fix minitest expection calls --- test/cases/coerced_tests.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/cases/coerced_tests.rb b/test/cases/coerced_tests.rb index 6bcf406b6..a75c0171c 100644 --- a/test/cases/coerced_tests.rb +++ b/test/cases/coerced_tests.rb @@ -192,14 +192,14 @@ def test_should_return_decimal_average_of_integer_field_coerced def test_limit_is_kept_coerced queries = capture_sql_ss { Account.limit(1).count } assert_equal 1, queries.length - queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1} + _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1} end coerce_tests! :test_limit_with_offset_is_kept def test_limit_with_offset_is_kept_coerced queries = capture_sql_ss { Account.limit(1).offset(1).count } assert_equal 1, queries.length - queries.first.must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1} + _(queries.first).must_match %r{ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1} end # SQL Server needs an alias for the calculated column @@ -265,7 +265,7 @@ class ColumnAttributesTest < ActiveRecord::TestCase def test_add_column_without_limit_coerced add_column :test_models, :description, :string, limit: nil TestModel.reset_column_information - TestModel.columns_hash["description"].limit.must_equal 4000 + _(TestModel.columns_hash["description"].limit).must_equal 4000 end end end @@ -615,14 +615,14 @@ class PersistenceTest < ActiveRecord::TestCase coerce_tests! :test_update_all_doesnt_ignore_order def test_update_all_doesnt_ignore_order_coerced david, mary = authors(:david), authors(:mary) - david.id.must_equal 1 - mary.id.must_equal 2 - david.name.wont_equal mary.name + _(david.id).must_equal 1 + _(mary.id).must_equal 2 + _(david.name).wont_equal mary.name assert_sql(/UPDATE.*\(SELECT \[authors\].\[id\] FROM \[authors\].*ORDER BY \[authors\].\[id\]/i) do Author.where('[id] > 1').order(:id).update_all(name: 'Test') end - david.reload.name.must_equal 'David' - mary.reload.name.must_equal 'Test' + _(david.reload.name).must_equal 'David' + _(mary.reload.name).must_equal 'Test' end # We can not UPDATE identity columns. From fd066869abd0573e4f259657196ceffe205db492 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Wed, 26 Feb 2020 14:42:06 +0000 Subject: [PATCH 4/9] Calculate should not remove ordering for MSSQL --- .../sqlserver/core_ext/calculations.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb index cfdb65453..d2b7096c7 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb @@ -6,6 +6,25 @@ module ConnectionAdapters module SQLServer module CoreExt module Calculations + + # Same as original except we don't perform PostgreSQL hack that removes ordering. + def calculate(operation, column_name) + if has_include?(column_name) + relation = apply_join_dependency + + if operation.to_s.downcase == "count" + unless distinct_value || distinct_select?(column_name || select_for_count) + relation.distinct! + relation.select_values = [ klass.primary_key || table[Arel.star] ] + end + end + + relation.calculate(operation, column_name) + else + perform_calculation(operation, column_name) + end + end + private def build_count_subquery(relation, column_name, distinct) From 3db2d6095c530bc22bf6ef2094a22c03b69f3068 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Thu, 27 Feb 2020 11:34:31 +0000 Subject: [PATCH 5/9] Order by selected items when using distinct exists --- .../sqlserver/core_ext/finder_methods.rb | 43 +++++++++++++++++++ .../connection_adapters/sqlserver_adapter.rb | 1 + 2 files changed, 44 insertions(+) create mode 100644 lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb new file mode 100644 index 000000000..fc9ff9db3 --- /dev/null +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb @@ -0,0 +1,43 @@ +require 'active_record/relation' +require 'active_record/version' + +module ActiveRecord + module ConnectionAdapters + module SQLServer + module CoreExt + module FinderMethods + + private + + # Same as original except we order by values in distinct select if present. + def construct_relation_for_exists(conditions) + if distinct_value && offset_value + relation = limit!(1) + + if select_values.present? + relation = relation.order(*select_values) + else + relation = relation.except(:order) + end + else + relation = except(:select, :distinct, :order)._select!(::ActiveRecord::FinderMethods::ONE_AS_ONE).limit!(1) + end + + case conditions + when Array, Hash + relation.where!(conditions) unless conditions.empty? + else + relation.where!(primary_key => conditions) unless conditions == :none + end + + relation + end + end + end + end + end +end + +ActiveSupport.on_load(:active_record) do + ActiveRecord::Relation.include(ActiveRecord::ConnectionAdapters::SQLServer::CoreExt::FinderMethods) +end diff --git a/lib/active_record/connection_adapters/sqlserver_adapter.rb b/lib/active_record/connection_adapters/sqlserver_adapter.rb index b3f745ac6..cc8564320 100644 --- a/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -7,6 +7,7 @@ require 'active_record/connection_adapters/sqlserver/core_ext/explain' require 'active_record/connection_adapters/sqlserver/core_ext/explain_subscriber' require 'active_record/connection_adapters/sqlserver/core_ext/attribute_methods' +require 'active_record/connection_adapters/sqlserver/core_ext/finder_methods' require 'active_record/connection_adapters/sqlserver/version' require 'active_record/connection_adapters/sqlserver/type' require 'active_record/connection_adapters/sqlserver/database_limits' From 5e4647e8b5850af49c19a14a4caa420cd6d1f717 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Thu, 27 Feb 2020 15:16:35 +0000 Subject: [PATCH 6/9] Default precision for 'time' column type is 7 --- .../sqlserver/type/time.rb | 5 ++- test/cases/column_test_sqlserver.rb | 40 +++++++++++++++++-- test/cases/schema_dumper_test_sqlserver.rb | 1 + test/schema/datatypes/2012.sql | 1 + 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/active_record/connection_adapters/sqlserver/type/time.rb b/lib/active_record/connection_adapters/sqlserver/type/time.rb index f8bc0dec8..6a7354f33 100644 --- a/lib/active_record/connection_adapters/sqlserver/type/time.rb +++ b/lib/active_record/connection_adapters/sqlserver/type/time.rb @@ -4,6 +4,9 @@ module SQLServer module Type class Time < ActiveRecord::Type::Time + # Default fractional scale for 'time' (See https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql) + DEFAULT_FRACTIONAL_SCALE = 7 + include TimeValueFractional2 def serialize(value) @@ -42,7 +45,7 @@ def cast_value(value) end def fractional_scale - precision + precision || DEFAULT_FRACTIONAL_SCALE end end diff --git a/test/cases/column_test_sqlserver.rb b/test/cases/column_test_sqlserver.rb index 796470436..9e41e81e3 100644 --- a/test/cases/column_test_sqlserver.rb +++ b/test/cases/column_test_sqlserver.rb @@ -349,7 +349,7 @@ def assert_obj_set_and_save(attribute, value) end it 'datetime2' do - skip 'datetime2 not supported in this protocal version' unless connection_dblib_73? + skip 'datetime2 not supported in this protocol version' unless connection_dblib_73? col = column('datetime2_7') _(col.sql_type).must_equal 'datetime2(7)' _(col.type).must_equal :datetime @@ -414,7 +414,7 @@ def assert_obj_set_and_save(attribute, value) end it 'datetimeoffset' do - skip 'datetimeoffset not supported in this protocal version' unless connection_dblib_73? + skip 'datetimeoffset not supported in this protocol version' unless connection_dblib_73? col = column('datetimeoffset_7') _(col.sql_type).must_equal 'datetimeoffset(7)' _(col.type).must_equal :datetimeoffset @@ -480,7 +480,7 @@ def assert_obj_set_and_save(attribute, value) end it 'time(7)' do - skip 'time() not supported in this protocal version' unless connection_dblib_73? + skip 'time() not supported in this protocol version' unless connection_dblib_73? col = column('time_7') _(col.sql_type).must_equal 'time(7)' _(col.type).must_equal :time @@ -512,7 +512,7 @@ def assert_obj_set_and_save(attribute, value) end it 'time(2)' do - skip 'time() not supported in this protocal version' unless connection_dblib_73? + skip 'time() not supported in this protocol version' unless connection_dblib_73? col = column('time_2') _(col.sql_type).must_equal 'time(2)' _(col.type).must_equal :time @@ -541,6 +541,38 @@ def assert_obj_set_and_save(attribute, value) _(obj.time_2).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 0), "Microseconds were <#{obj.time_2.usec}> vs <0>" end + it 'time using default precision' do + skip 'time() not supported in this protocol version' unless connection_dblib_73? + col = column('time_default') + _(col.sql_type).must_equal 'time(7)' + _(col.type).must_equal :time + _(col.null).must_equal true + _(col.default).must_equal Time.utc(1900, 01, 01, 15, 03, 42, Rational(62197800, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <62197800>" + _(col.default_function).must_be_nil + type = connection.lookup_cast_type_from_column(col) + _(type).must_be_instance_of Type::Time + _(type.limit).must_be_nil + _(type.precision).must_equal 7 + _(type.scale).must_be_nil + # Time's #usec precision (low micro) + obj.time_default = Time.utc(2000, 01, 01, 15, 45, 00, 300) + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>" + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>" + obj.save! ; obj.reload + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Microseconds were <#{obj.time_default.usec}> vs <0>" + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 300), "Nanoseconds were <#{obj.time_default.nsec}> vs <300>" + # Time's #usec precision (high micro) + obj.time_default = Time.utc(2000, 01, 01, 15, 45, 00, 234567) + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>" + obj.save! ; obj.reload + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, 234567), "Microseconds were <#{obj.time_default.usec}> vs <234567>" + # Time's #usec precision (high nano rounded) + obj.time_default = Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321545, 1000)) + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>" + obj.save! ; obj.reload + _(obj.time_default).must_equal Time.utc(2000, 01, 01, 15, 45, 00, Rational(288321500, 1000)), "Nanoseconds were <#{obj.time_default.nsec}> vs <288321500>" + end + # Character Strings it 'char(10)' do diff --git a/test/cases/schema_dumper_test_sqlserver.rb b/test/cases/schema_dumper_test_sqlserver.rb index 3da17ca1c..47b96cff3 100644 --- a/test/cases/schema_dumper_test_sqlserver.rb +++ b/test/cases/schema_dumper_test_sqlserver.rb @@ -34,6 +34,7 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase if connection_dblib_73? assert_line :time_7, type: 'time', limit: nil, precision: 7, scale: nil, default: "04:20:00.2883215" assert_line :time_2, type: 'time', limit: nil, precision: 2, scale: nil, default: nil + assert_line :time_default, type: 'time', limit: nil, precision: 7, scale: nil, default: "15:03:42.0621978" end # Character Strings assert_line :char_10, type: 'char', limit: 10, precision: nil, scale: nil, default: "1234567890", collation: nil diff --git a/test/schema/datatypes/2012.sql b/test/schema/datatypes/2012.sql index 044b78c97..77b14807d 100644 --- a/test/schema/datatypes/2012.sql +++ b/test/schema/datatypes/2012.sql @@ -35,6 +35,7 @@ CREATE TABLE [sst_datatypes] ( [smalldatetime] [smalldatetime] NULL DEFAULT '1901-01-01T15:45:00.000Z', [time_7] [time](7) NULL DEFAULT '04:20:00.2883215', [time_2] [time](2) NULL, + [time_default] [time] NULL DEFAULT '15:03:42.0621978', -- Character Strings [char_10] [char](10) NULL DEFAULT '1234567890', [varchar_50] [varchar](50) NULL DEFAULT 'test varchar_50', From 64f38c54cf23b253fdde5fb9a708bbba3526c071 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Thu, 19 Mar 2020 15:55:39 +0000 Subject: [PATCH 7/9] Set default time precision when registering time type --- .../connection_adapters/sqlserver/type/time.rb | 5 +---- lib/active_record/connection_adapters/sqlserver_adapter.rb | 6 ++++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/active_record/connection_adapters/sqlserver/type/time.rb b/lib/active_record/connection_adapters/sqlserver/type/time.rb index 6a7354f33..f8bc0dec8 100644 --- a/lib/active_record/connection_adapters/sqlserver/type/time.rb +++ b/lib/active_record/connection_adapters/sqlserver/type/time.rb @@ -4,9 +4,6 @@ module SQLServer module Type class Time < ActiveRecord::Type::Time - # Default fractional scale for 'time' (See https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql) - DEFAULT_FRACTIONAL_SCALE = 7 - include TimeValueFractional2 def serialize(value) @@ -45,7 +42,7 @@ def cast_value(value) end def fractional_scale - precision || DEFAULT_FRACTIONAL_SCALE + precision end end diff --git a/lib/active_record/connection_adapters/sqlserver_adapter.rb b/lib/active_record/connection_adapters/sqlserver_adapter.rb index cc8564320..0b875cb10 100644 --- a/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -41,6 +41,9 @@ class SQLServerAdapter < AbstractAdapter ADAPTER_NAME = 'SQLServer'.freeze + # Default precision for 'time' (See https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql) + DEFAULT_TIME_PRECISION = 7 + attr_reader :spid cattr_accessor :cs_equality_operator, instance_accessor: false @@ -297,8 +300,7 @@ def initialize_type_map(m = type_map) end m.register_type 'smalldatetime', SQLServer::Type::SmallDateTime.new m.register_type %r{\Atime}i do |sql_type| - scale = extract_scale(sql_type) - precision = extract_precision(sql_type) + precision = extract_precision(sql_type) || DEFAULT_TIME_PRECISION SQLServer::Type::Time.new precision: precision end # Character Strings From a3565cc6dd363c55e5646b34553ae9cccb41f176 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Mon, 23 Mar 2020 16:48:49 +0000 Subject: [PATCH 8/9] Adapter does not use prepared statement cache --- test/cases/coerced_tests.rb | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/cases/coerced_tests.rb b/test/cases/coerced_tests.rb index a75c0171c..6dff353b7 100644 --- a/test/cases/coerced_tests.rb +++ b/test/cases/coerced_tests.rb @@ -145,8 +145,27 @@ def test_belongs_to_with_primary_key_joins_on_correct_column_coerced module ActiveRecord class BindParameterTest < ActiveRecord::TestCase - # Never finds `sql` since we use `EXEC sp_executesql` wrappers. + # Same as original coerced test except log is found using `EXEC sp_executesql` wrapper. coerce_tests! :test_binds_are_logged + def test_binds_are_logged_coerced + sub = Arel::Nodes::BindParam.new(1) + binds = [Relation::QueryAttribute.new("id", 1, Type::Value.new)] + sql = "select * from topics where id = #{sub.to_sql}" + + @connection.exec_query(sql, "SQL", binds) + + logged_sql = "EXEC sp_executesql N'#{sql}', N'#{sub.to_sql} int', #{sub.to_sql} = 1" + message = @subscriber.calls.find { |args| args[4][:sql] == logged_sql } + + assert_equal binds, message[4][:binds] + end + + # SQL Server adapter does not use a statement cache as query plans are already reused using `EXEC sp_executesql`. + coerce_tests! :test_statement_cache + coerce_tests! :test_statement_cache_with_query_cache + coerce_tests! :test_statement_cache_with_find_by + coerce_tests! :test_statement_cache_with_in_clause + coerce_tests! :test_statement_cache_with_sql_string_literal end end From c2be57cc2f0a81887d2d9f6e943c6b10601f6c9c Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 24 Mar 2020 17:08:19 +0000 Subject: [PATCH 9/9] Quoted table names containing square brackets need to be regex escaped Use method from Rails master --- .../sqlserver/core_ext/query_methods.rb | 26 +++++++++++++++++++ .../connection_adapters/sqlserver_adapter.rb | 1 + 2 files changed, 27 insertions(+) create mode 100644 lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb new file mode 100644 index 000000000..b9f4529dd --- /dev/null +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb @@ -0,0 +1,26 @@ +require 'active_record/relation' +require 'active_record/version' + +module ActiveRecord + module ConnectionAdapters + module SQLServer + module CoreExt + module QueryMethods + + private + + # Copy of original from Rails master. This patch can be removed when adapter supports Rails 6. + def table_name_matches?(from) + table_name = Regexp.escape(table.name) + quoted_table_name = Regexp.escape(connection.quote_table_name(table.name)) + /(?:\A|(?