activerecord-sqlserver-adapter 5.2.1 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.editorconfig +9 -0
- data/.github/issue_template.md +23 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +29 -0
- data/.travis.yml +6 -8
- data/CHANGELOG.md +38 -24
- data/{Dockerfile → Dockerfile.ci} +1 -1
- data/Gemfile +48 -41
- data/Guardfile +9 -8
- data/README.md +9 -30
- data/RUNNING_UNIT_TESTS.md +3 -0
- data/Rakefile +14 -16
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +25 -14
- data/appveyor.yml +24 -17
- data/docker-compose.ci.yml +7 -5
- data/guides/RELEASING.md +11 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +2 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +3 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +5 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +8 -7
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +36 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +6 -4
- data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +88 -44
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +9 -12
- data/lib/active_record/connection_adapters/sqlserver/errors.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +46 -8
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +16 -5
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +9 -7
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +190 -164
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +8 -8
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +43 -44
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +7 -9
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +5 -4
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +7 -4
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +4 -3
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +8 -8
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +5 -4
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/json.rb +2 -1
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +4 -4
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +4 -4
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/string.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +6 -6
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +8 -9
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +5 -4
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +6 -5
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +4 -4
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +4 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +6 -5
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +4 -4
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +6 -5
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +4 -4
- data/lib/active_record/connection_adapters/sqlserver/type.rb +37 -35
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +10 -11
- data/lib/active_record/connection_adapters/sqlserver/version.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +128 -92
- data/lib/active_record/connection_adapters/sqlserver_column.rb +9 -5
- data/lib/active_record/sqlserver_base.rb +9 -1
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +28 -32
- data/lib/activerecord-sqlserver-adapter.rb +3 -1
- data/lib/arel/visitors/sqlserver.rb +58 -24
- data/lib/arel_sqlserver.rb +4 -2
- data/test/appveyor/dbsetup.ps1 +4 -4
- data/test/cases/adapter_test_sqlserver.rb +214 -171
- data/test/cases/change_column_null_test_sqlserver.rb +14 -12
- data/test/cases/coerced_tests.rb +631 -356
- data/test/cases/column_test_sqlserver.rb +283 -284
- data/test/cases/connection_test_sqlserver.rb +17 -20
- data/test/cases/execute_procedure_test_sqlserver.rb +20 -20
- data/test/cases/fetch_test_sqlserver.rb +16 -22
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +15 -19
- data/test/cases/helper_sqlserver.rb +15 -15
- data/test/cases/in_clause_test_sqlserver.rb +36 -0
- data/test/cases/index_test_sqlserver.rb +15 -15
- data/test/cases/json_test_sqlserver.rb +25 -25
- data/test/cases/migration_test_sqlserver.rb +25 -29
- data/test/cases/order_test_sqlserver.rb +53 -54
- data/test/cases/pessimistic_locking_test_sqlserver.rb +27 -33
- data/test/cases/rake_test_sqlserver.rb +33 -45
- data/test/cases/schema_dumper_test_sqlserver.rb +107 -109
- data/test/cases/schema_test_sqlserver.rb +20 -26
- data/test/cases/scratchpad_test_sqlserver.rb +4 -4
- data/test/cases/showplan_test_sqlserver.rb +28 -35
- data/test/cases/specific_schema_test_sqlserver.rb +68 -65
- data/test/cases/transaction_test_sqlserver.rb +18 -20
- data/test/cases/trigger_test_sqlserver.rb +14 -13
- data/test/cases/utils_test_sqlserver.rb +70 -70
- data/test/cases/uuid_test_sqlserver.rb +13 -14
- data/test/debug.rb +8 -6
- data/test/migrations/create_clients_and_change_column_null.rb +3 -1
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +4 -4
- data/test/models/sqlserver/booking.rb +3 -1
- data/test/models/sqlserver/customers_view.rb +3 -1
- data/test/models/sqlserver/datatype.rb +2 -0
- data/test/models/sqlserver/datatype_migration.rb +2 -0
- data/test/models/sqlserver/dollar_table_name.rb +3 -1
- data/test/models/sqlserver/edge_schema.rb +3 -3
- data/test/models/sqlserver/fk_has_fk.rb +3 -1
- data/test/models/sqlserver/fk_has_pk.rb +3 -1
- data/test/models/sqlserver/natural_pk_data.rb +4 -2
- data/test/models/sqlserver/natural_pk_int_data.rb +3 -1
- data/test/models/sqlserver/no_pk_data.rb +3 -1
- data/test/models/sqlserver/object_default.rb +3 -1
- data/test/models/sqlserver/quoted_table.rb +4 -2
- data/test/models/sqlserver/quoted_view_1.rb +3 -1
- data/test/models/sqlserver/quoted_view_2.rb +3 -1
- data/test/models/sqlserver/sst_memory.rb +3 -1
- data/test/models/sqlserver/string_default.rb +3 -1
- data/test/models/sqlserver/string_defaults_big_view.rb +3 -1
- data/test/models/sqlserver/string_defaults_view.rb +3 -1
- data/test/models/sqlserver/tinyint_pk.rb +3 -1
- data/test/models/sqlserver/trigger.rb +4 -2
- data/test/models/sqlserver/trigger_history.rb +3 -1
- data/test/models/sqlserver/upper.rb +3 -1
- data/test/models/sqlserver/uppered.rb +3 -1
- data/test/models/sqlserver/uuid.rb +3 -1
- data/test/schema/sqlserver_specific_schema.rb +22 -22
- data/test/support/coerceable_test_sqlserver.rb +15 -9
- data/test/support/connection_reflection.rb +3 -2
- data/test/support/core_ext/query_cache.rb +4 -1
- data/test/support/load_schema_sqlserver.rb +5 -5
- data/test/support/minitest_sqlserver.rb +3 -1
- data/test/support/paths_sqlserver.rb +11 -11
- data/test/support/rake_helpers.rb +13 -10
- data/test/support/sql_counter_sqlserver.rb +3 -4
- data/test/support/test_in_memory_oltp.rb +9 -7
- metadata +17 -7
data/test/cases/coerced_tests.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "cases/helper_sqlserver"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
require 'models/event'
|
|
5
|
+
require "models/event"
|
|
6
6
|
class UniquenessValidationTest < ActiveRecord::TestCase
|
|
7
|
-
# So sp_executesql swallows this exception. Run without
|
|
7
|
+
# So sp_executesql swallows this exception. Run without prepared to see it.
|
|
8
8
|
coerce_tests! :test_validate_uniqueness_with_limit
|
|
9
9
|
def test_validate_uniqueness_with_limit_coerced
|
|
10
10
|
connection.unprepared_statement do
|
|
@@ -14,7 +14,7 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
# So sp_executesql swallows this exception. Run without
|
|
17
|
+
# So sp_executesql swallows this exception. Run without prepared to see it.
|
|
18
18
|
coerce_tests! :test_validate_uniqueness_with_limit_and_utf8
|
|
19
19
|
def test_validate_uniqueness_with_limit_and_utf8_coerced
|
|
20
20
|
connection.unprepared_statement do
|
|
@@ -23,66 +23,125 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
26
|
|
|
27
|
+
# Skip the test if database is case-insensitive.
|
|
28
|
+
coerce_tests! :test_validate_case_sensitive_uniqueness_by_default
|
|
29
|
+
def test_validate_case_sensitive_uniqueness_by_default_coerced
|
|
30
|
+
database_collation = connection.select_one("SELECT collation_name FROM sys.databases WHERE name = 'activerecord_unittest'").values.first
|
|
31
|
+
skip if database_collation.include?("_CI_")
|
|
29
32
|
|
|
33
|
+
original_test_validate_case_sensitive_uniqueness_by_default_coerced
|
|
34
|
+
end
|
|
35
|
+
end
|
|
30
36
|
|
|
31
|
-
require
|
|
37
|
+
require "models/event"
|
|
32
38
|
module ActiveRecord
|
|
33
39
|
class AdapterTest < ActiveRecord::TestCase
|
|
34
|
-
# I really
|
|
40
|
+
# I really don`t think we can support legacy binds.
|
|
35
41
|
coerce_tests! :test_select_all_with_legacy_binds
|
|
36
42
|
coerce_tests! :test_insert_update_delete_with_legacy_binds
|
|
37
43
|
|
|
38
44
|
# As far as I can tell, SQL Server does not support null bytes in strings.
|
|
39
45
|
coerce_tests! :test_update_prepared_statement
|
|
40
46
|
|
|
41
|
-
# So sp_executesql swallows this exception. Run without
|
|
47
|
+
# So sp_executesql swallows this exception. Run without prepared to see it.
|
|
42
48
|
coerce_tests! :test_value_limit_violations_are_translated_to_specific_exception
|
|
43
49
|
def test_value_limit_violations_are_translated_to_specific_exception_coerced
|
|
44
50
|
connection.unprepared_statement do
|
|
45
51
|
error = assert_raises(ActiveRecord::ValueTooLong) do
|
|
46
|
-
Event.create(title:
|
|
52
|
+
Event.create(title: "abcdefgh")
|
|
47
53
|
end
|
|
48
54
|
assert_not_nil error.cause
|
|
49
55
|
end
|
|
50
56
|
end
|
|
57
|
+
|
|
58
|
+
# Fix randomly failing test. The loading of the model's schema was affecting the test.
|
|
59
|
+
coerce_tests! :test_errors_when_an_insert_query_is_called_while_preventing_writes
|
|
60
|
+
def test_errors_when_an_insert_query_is_called_while_preventing_writes_coerced
|
|
61
|
+
Subscriber.send(:load_schema!)
|
|
62
|
+
original_test_errors_when_an_insert_query_is_called_while_preventing_writes
|
|
63
|
+
end
|
|
51
64
|
end
|
|
52
65
|
end
|
|
53
66
|
|
|
67
|
+
module ActiveRecord
|
|
68
|
+
class AdapterTestWithoutTransaction < ActiveRecord::TestCase
|
|
69
|
+
# SQL Server does not allow truncation of tables that are referenced by foreign key
|
|
70
|
+
# constraints. So manually remove/add foreign keys in test.
|
|
71
|
+
coerce_tests! :test_truncate_tables
|
|
72
|
+
def test_truncate_tables_coerced
|
|
73
|
+
# Remove foreign key constraint to allow truncation.
|
|
74
|
+
@connection.remove_foreign_key :authors, :author_addresses
|
|
75
|
+
|
|
76
|
+
assert_operator Post.count, :>, 0
|
|
77
|
+
assert_operator Author.count, :>, 0
|
|
78
|
+
assert_operator AuthorAddress.count, :>, 0
|
|
79
|
+
|
|
80
|
+
@connection.truncate_tables("author_addresses", "authors", "posts")
|
|
81
|
+
|
|
82
|
+
assert_equal 0, Post.count
|
|
83
|
+
assert_equal 0, Author.count
|
|
84
|
+
assert_equal 0, AuthorAddress.count
|
|
85
|
+
ensure
|
|
86
|
+
reset_fixtures("posts", "authors", "author_addresses")
|
|
87
|
+
|
|
88
|
+
# Restore foreign key constraint.
|
|
89
|
+
@connection.add_foreign_key :authors, :author_addresses
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# SQL Server does not allow truncation of tables that are referenced by foreign key
|
|
93
|
+
# constraints. So manually remove/add foreign keys in test.
|
|
94
|
+
coerce_tests! :test_truncate_tables_with_query_cache
|
|
95
|
+
def test_truncate_tables_with_query_cache
|
|
96
|
+
# Remove foreign key constraint to allow truncation.
|
|
97
|
+
@connection.remove_foreign_key :authors, :author_addresses
|
|
98
|
+
|
|
99
|
+
@connection.enable_query_cache!
|
|
100
|
+
|
|
101
|
+
assert_operator Post.count, :>, 0
|
|
102
|
+
assert_operator Author.count, :>, 0
|
|
103
|
+
assert_operator AuthorAddress.count, :>, 0
|
|
54
104
|
|
|
105
|
+
@connection.truncate_tables("author_addresses", "authors", "posts")
|
|
55
106
|
|
|
107
|
+
assert_equal 0, Post.count
|
|
108
|
+
assert_equal 0, Author.count
|
|
109
|
+
assert_equal 0, AuthorAddress.count
|
|
110
|
+
ensure
|
|
111
|
+
reset_fixtures("posts", "authors", "author_addresses")
|
|
112
|
+
@connection.disable_query_cache!
|
|
56
113
|
|
|
57
|
-
|
|
114
|
+
# Restore foreign key constraint.
|
|
115
|
+
@connection.add_foreign_key :authors, :author_addresses
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
require "models/topic"
|
|
58
121
|
class AttributeMethodsTest < ActiveRecord::TestCase
|
|
122
|
+
# Use IFF for boolean statement in SELECT
|
|
59
123
|
coerce_tests! %r{typecast attribute from select to false}
|
|
60
124
|
def test_typecast_attribute_from_select_to_false_coerced
|
|
61
|
-
Topic.create(:title =>
|
|
125
|
+
Topic.create(:title => "Budget")
|
|
62
126
|
topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 2, 1, 0) as is_test").first
|
|
63
|
-
|
|
127
|
+
assert_not_predicate topic, :is_test?
|
|
64
128
|
end
|
|
65
129
|
|
|
130
|
+
# Use IFF for boolean statement in SELECT
|
|
66
131
|
coerce_tests! %r{typecast attribute from select to true}
|
|
67
132
|
def test_typecast_attribute_from_select_to_true_coerced
|
|
68
|
-
Topic.create(:title =>
|
|
133
|
+
Topic.create(:title => "Budget")
|
|
69
134
|
topic = Topic.all.merge!(:select => "topics.*, IIF (1 = 1, 1, 0) as is_test").first
|
|
70
|
-
|
|
135
|
+
assert_predicate topic, :is_test?
|
|
71
136
|
end
|
|
72
137
|
end
|
|
73
138
|
|
|
74
|
-
|
|
75
|
-
class NumericDataTest < ActiveRecord::TestCase
|
|
76
|
-
# We do not have do the DecimalWithoutScale type.
|
|
77
|
-
coerce_tests! :test_numeric_fields
|
|
78
|
-
coerce_tests! :test_numeric_fields_with_scale
|
|
79
|
-
end
|
|
80
|
-
|
|
81
139
|
class BasicsTest < ActiveRecord::TestCase
|
|
140
|
+
# Use square brackets as SQL Server escaped character
|
|
82
141
|
coerce_tests! :test_column_names_are_escaped
|
|
83
142
|
def test_column_names_are_escaped_coerced
|
|
84
143
|
conn = ActiveRecord::Base.connection
|
|
85
|
-
assert_equal
|
|
144
|
+
assert_equal "[t]]]", conn.quote_column_name("t]")
|
|
86
145
|
end
|
|
87
146
|
|
|
88
147
|
# Just like PostgreSQLAdapter does.
|
|
@@ -96,52 +155,60 @@ class BasicsTest < ActiveRecord::TestCase
|
|
|
96
155
|
Time.use_zone("Eastern Time (US & Canada)") do
|
|
97
156
|
topic = Topic.find(1)
|
|
98
157
|
time = Time.zone.parse("2017-07-17 10:56")
|
|
99
|
-
topic.
|
|
158
|
+
topic.update!(written_on: time)
|
|
100
159
|
assert_equal(time, topic.written_on)
|
|
101
160
|
end
|
|
102
161
|
end
|
|
103
162
|
|
|
104
163
|
def test_update_date_time_attributes_with_default_timezone_local
|
|
105
|
-
with_env_tz
|
|
164
|
+
with_env_tz "America/New_York" do
|
|
106
165
|
with_timezone_config default: :local do
|
|
107
166
|
Time.use_zone("Eastern Time (US & Canada)") do
|
|
108
167
|
topic = Topic.find(1)
|
|
109
168
|
time = Time.zone.parse("2017-07-17 10:56")
|
|
110
|
-
topic.
|
|
169
|
+
topic.update!(written_on: time)
|
|
111
170
|
assert_equal(time, topic.written_on)
|
|
112
171
|
end
|
|
113
172
|
end
|
|
114
173
|
end
|
|
115
174
|
end
|
|
116
175
|
|
|
117
|
-
#
|
|
118
|
-
coerce_tests! %r{
|
|
119
|
-
test "
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
176
|
+
# SQL Server does not have query for release_savepoint
|
|
177
|
+
coerce_tests! %r{an empty transaction does not raise if preventing writes}
|
|
178
|
+
test "an empty transaction does not raise if preventing writes coerced" do
|
|
179
|
+
ActiveRecord::Base.connection_handler.while_preventing_writes do
|
|
180
|
+
assert_queries(1, ignore_none: true) do
|
|
181
|
+
Bird.transaction do
|
|
182
|
+
ActiveRecord::Base.connection.materialize_transactions
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
125
186
|
end
|
|
126
187
|
end
|
|
127
188
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
189
|
class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|
132
190
|
# Since @client.firm is a single first/top, and we use FETCH the order clause is used.
|
|
133
191
|
coerce_tests! :test_belongs_to_does_not_use_order_by
|
|
134
192
|
|
|
193
|
+
# Square brackets around column name
|
|
135
194
|
coerce_tests! :test_belongs_to_with_primary_key_joins_on_correct_column
|
|
136
195
|
def test_belongs_to_with_primary_key_joins_on_correct_column_coerced
|
|
137
196
|
sql = Client.joins(:firm_with_primary_key).to_sql
|
|
138
197
|
assert_no_match(/\[firm_with_primary_keys_companies\]\.\[id\]/, sql)
|
|
139
198
|
assert_match(/\[firm_with_primary_keys_companies\]\.\[name\]/, sql)
|
|
140
199
|
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
|
|
144
200
|
|
|
201
|
+
# Asserted SQL to get one row different from original test.
|
|
202
|
+
coerce_tests! :test_belongs_to
|
|
203
|
+
def test_belongs_to_coerced
|
|
204
|
+
client = Client.find(3)
|
|
205
|
+
first_firm = companies(:first_firm)
|
|
206
|
+
assert_sql(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
|
|
207
|
+
assert_equal first_firm, client.firm
|
|
208
|
+
assert_equal first_firm.name, client.firm.name
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
145
212
|
|
|
146
213
|
module ActiveRecord
|
|
147
214
|
class BindParameterTest < ActiveRecord::TestCase
|
|
@@ -163,62 +230,53 @@ module ActiveRecord
|
|
|
163
230
|
# SQL Server adapter does not use a statement cache as query plans are already reused using `EXEC sp_executesql`.
|
|
164
231
|
coerce_tests! :test_statement_cache
|
|
165
232
|
coerce_tests! :test_statement_cache_with_query_cache
|
|
233
|
+
coerce_tests! :test_statement_cache_with_find
|
|
166
234
|
coerce_tests! :test_statement_cache_with_find_by
|
|
167
235
|
coerce_tests! :test_statement_cache_with_in_clause
|
|
168
236
|
coerce_tests! :test_statement_cache_with_sql_string_literal
|
|
169
237
|
end
|
|
170
238
|
end
|
|
171
239
|
|
|
172
|
-
|
|
173
240
|
module ActiveRecord
|
|
174
241
|
class InstrumentationTest < ActiveRecord::TestCase
|
|
175
|
-
#
|
|
242
|
+
# Fix randomly failing test. The loading of the model's schema was affecting the test.
|
|
176
243
|
coerce_tests! :test_payload_name_on_load
|
|
177
244
|
def test_payload_name_on_load_coerced
|
|
178
|
-
Book.
|
|
179
|
-
|
|
180
|
-
subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
|
|
181
|
-
event = ActiveSupport::Notifications::Event.new(*args)
|
|
182
|
-
if event.payload[:sql].match "SELECT"
|
|
183
|
-
assert_equal "Book Load", event.payload[:name]
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
Book.first
|
|
187
|
-
ensure
|
|
188
|
-
ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber
|
|
245
|
+
Book.send(:load_schema!)
|
|
246
|
+
original_test_payload_name_on_load
|
|
189
247
|
end
|
|
190
248
|
end
|
|
191
249
|
end
|
|
192
250
|
|
|
193
251
|
class CalculationsTest < ActiveRecord::TestCase
|
|
194
|
-
#
|
|
252
|
+
# Fix randomly failing test. The loading of the model's schema was affecting the test.
|
|
195
253
|
coerce_tests! :test_offset_is_kept
|
|
196
254
|
def test_offset_is_kept_coerced
|
|
197
|
-
Account.
|
|
198
|
-
|
|
199
|
-
assert_equal 1, queries.length
|
|
200
|
-
assert_match(/OFFSET/, queries.first)
|
|
255
|
+
Account.send(:load_schema!)
|
|
256
|
+
original_test_offset_is_kept
|
|
201
257
|
end
|
|
202
258
|
|
|
203
259
|
# Are decimal, not integer.
|
|
204
260
|
coerce_tests! :test_should_return_decimal_average_of_integer_field
|
|
205
261
|
def test_should_return_decimal_average_of_integer_field_coerced
|
|
206
262
|
value = Account.average(:id)
|
|
207
|
-
assert_equal BigDecimal(
|
|
263
|
+
assert_equal BigDecimal("3.0").to_s, BigDecimal(value).to_s
|
|
208
264
|
end
|
|
209
265
|
|
|
266
|
+
# Match SQL Server limit implementation
|
|
210
267
|
coerce_tests! :test_limit_is_kept
|
|
211
268
|
def test_limit_is_kept_coerced
|
|
212
269
|
queries = capture_sql_ss { Account.limit(1).count }
|
|
213
270
|
assert_equal 1, queries.length
|
|
214
|
-
|
|
271
|
+
assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/, queries.first)
|
|
215
272
|
end
|
|
216
273
|
|
|
274
|
+
# Match SQL Server limit implementation
|
|
217
275
|
coerce_tests! :test_limit_with_offset_is_kept
|
|
218
276
|
def test_limit_with_offset_is_kept_coerced
|
|
219
277
|
queries = capture_sql_ss { Account.limit(1).offset(1).count }
|
|
220
278
|
assert_equal 1, queries.length
|
|
221
|
-
|
|
279
|
+
assert_match(/ORDER BY \[accounts\]\.\[id\] ASC OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY.*@0 = 1, @1 = 1/, queries.first)
|
|
222
280
|
end
|
|
223
281
|
|
|
224
282
|
# SQL Server needs an alias for the calculated column
|
|
@@ -233,49 +291,57 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
|
233
291
|
coerce_tests! :test_having_with_strong_parameters
|
|
234
292
|
end
|
|
235
293
|
|
|
236
|
-
|
|
237
|
-
|
|
238
294
|
module ActiveRecord
|
|
239
295
|
class Migration
|
|
240
296
|
class ChangeSchemaTest < ActiveRecord::TestCase
|
|
241
|
-
|
|
242
|
-
coerce_tests! :
|
|
243
|
-
|
|
244
|
-
|
|
297
|
+
# Integer.default is a number and not a string
|
|
298
|
+
coerce_tests! :test_create_table_with_defaults
|
|
299
|
+
def test_create_table_with_defaults_coerce
|
|
300
|
+
connection.create_table :testings do |t|
|
|
301
|
+
t.column :one, :string, default: "hello"
|
|
302
|
+
t.column :two, :boolean, default: true
|
|
303
|
+
t.column :three, :boolean, default: false
|
|
304
|
+
t.column :four, :integer, default: 1
|
|
305
|
+
t.column :five, :text, default: "hello"
|
|
306
|
+
end
|
|
245
307
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
308
|
+
columns = connection.columns(:testings)
|
|
309
|
+
one = columns.detect { |c| c.name == "one" }
|
|
310
|
+
two = columns.detect { |c| c.name == "two" }
|
|
311
|
+
three = columns.detect { |c| c.name == "three" }
|
|
312
|
+
four = columns.detect { |c| c.name == "four" }
|
|
313
|
+
five = columns.detect { |c| c.name == "five" }
|
|
314
|
+
|
|
315
|
+
assert_equal "hello", one.default
|
|
316
|
+
assert_equal true, connection.lookup_cast_type_from_column(two).deserialize(two.default)
|
|
317
|
+
assert_equal false, connection.lookup_cast_type_from_column(three).deserialize(three.default)
|
|
318
|
+
assert_equal 1, four.default
|
|
319
|
+
assert_equal "hello", five.default
|
|
320
|
+
end
|
|
249
321
|
end
|
|
250
322
|
end
|
|
251
323
|
end
|
|
252
324
|
|
|
253
|
-
|
|
254
|
-
|
|
255
325
|
module ActiveRecord
|
|
256
326
|
module ConnectionAdapters
|
|
257
327
|
class QuoteARBaseTest < ActiveRecord::TestCase
|
|
258
|
-
|
|
259
328
|
# Use our date format.
|
|
260
329
|
coerce_tests! :test_quote_ar_object
|
|
261
330
|
def test_quote_ar_object_coerced
|
|
262
331
|
value = DatetimePrimaryKey.new(id: @time)
|
|
263
|
-
assert_equal "'02-14-2017 12:34:56.79'",
|
|
332
|
+
assert_equal "'02-14-2017 12:34:56.79'", @connection.quote(value)
|
|
264
333
|
end
|
|
265
334
|
|
|
266
335
|
# Use our date format.
|
|
267
336
|
coerce_tests! :test_type_cast_ar_object
|
|
268
337
|
def test_type_cast_ar_object_coerced
|
|
269
338
|
value = DatetimePrimaryKey.new(id: @time)
|
|
270
|
-
assert_equal "02-14-2017 12:34:56.79",
|
|
339
|
+
assert_equal "02-14-2017 12:34:56.79", @connection.type_cast(value)
|
|
271
340
|
end
|
|
272
|
-
|
|
273
341
|
end
|
|
274
342
|
end
|
|
275
343
|
end
|
|
276
344
|
|
|
277
|
-
|
|
278
|
-
|
|
279
345
|
module ActiveRecord
|
|
280
346
|
class Migration
|
|
281
347
|
class ColumnAttributesTest < ActiveRecord::TestCase
|
|
@@ -290,16 +356,13 @@ module ActiveRecord
|
|
|
290
356
|
end
|
|
291
357
|
end
|
|
292
358
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
359
|
module ActiveRecord
|
|
297
360
|
class Migration
|
|
298
|
-
class ColumnsTest
|
|
361
|
+
class ColumnsTest < ActiveRecord::TestCase
|
|
299
362
|
# Our defaults are real 70000 integers vs '70000' strings.
|
|
300
363
|
coerce_tests! :test_rename_column_preserves_default_value_not_null
|
|
301
364
|
def test_rename_column_preserves_default_value_not_null_coerced
|
|
302
|
-
add_column
|
|
365
|
+
add_column "test_models", "salary", :integer, :default => 70000
|
|
303
366
|
default_before = connection.columns("test_models").find { |c| c.name == "salary" }.default
|
|
304
367
|
assert_equal 70000, default_before
|
|
305
368
|
rename_column "test_models", "salary", "annual_salary"
|
|
@@ -315,9 +378,9 @@ module ActiveRecord
|
|
|
315
378
|
add_column "test_models", :hat_size, :integer
|
|
316
379
|
add_column "test_models", :hat_style, :string, :limit => 100
|
|
317
380
|
add_index "test_models", ["hat_style", "hat_size"], :unique => true
|
|
318
|
-
assert_equal 1, connection.indexes(
|
|
381
|
+
assert_equal 1, connection.indexes("test_models").size
|
|
319
382
|
remove_column("test_models", "hat_size")
|
|
320
|
-
assert_equal [], connection.indexes(
|
|
383
|
+
assert_equal [], connection.indexes("test_models").map(&:name)
|
|
321
384
|
end
|
|
322
385
|
|
|
323
386
|
# Choose `StatementInvalid` vs `ActiveRecordError`.
|
|
@@ -332,9 +395,6 @@ module ActiveRecord
|
|
|
332
395
|
end
|
|
333
396
|
end
|
|
334
397
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
398
|
class MigrationTest < ActiveRecord::TestCase
|
|
339
399
|
# We do not have do the DecimalWithoutScale type.
|
|
340
400
|
coerce_tests! :test_add_table_with_decimals
|
|
@@ -358,7 +418,7 @@ class MigrationTest < ActiveRecord::TestCase
|
|
|
358
418
|
assert_not_nil b.my_house_population
|
|
359
419
|
assert_not_nil b.value_of_e
|
|
360
420
|
assert_kind_of BigDecimal, b.world_population
|
|
361
|
-
assert_equal
|
|
421
|
+
assert_equal "6000000000.0", b.world_population.to_s
|
|
362
422
|
assert_kind_of Integer, b.my_house_population
|
|
363
423
|
assert_equal 3, b.my_house_population
|
|
364
424
|
assert_kind_of BigDecimal, b.bank_balance
|
|
@@ -374,19 +434,13 @@ class MigrationTest < ActiveRecord::TestCase
|
|
|
374
434
|
coerce_tests! :test_internal_metadata_stores_environment
|
|
375
435
|
end
|
|
376
436
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
437
|
class CoreTest < ActiveRecord::TestCase
|
|
381
|
-
# I think fixtures are
|
|
438
|
+
# I think fixtures are using the wrong time zone and the `:first`
|
|
382
439
|
# `topics`.`bonus_time` attribute of 2005-01-30t15:28:00.00+01:00 is
|
|
383
440
|
# getting local EST time for me and set to "09:28:00.0000000".
|
|
384
441
|
coerce_tests! :test_pretty_print_persisted
|
|
385
442
|
end
|
|
386
443
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
444
|
module ActiveRecord
|
|
391
445
|
module ConnectionAdapters
|
|
392
446
|
# Just like PostgreSQLAdapter does.
|
|
@@ -400,27 +454,152 @@ module ActiveRecord
|
|
|
400
454
|
end
|
|
401
455
|
end
|
|
402
456
|
|
|
457
|
+
module ActiveRecord
|
|
458
|
+
# The original module is hardcoded for PostgreSQL/SQLite/MySQL tests.
|
|
459
|
+
module DatabaseTasksSetupper
|
|
460
|
+
def setup
|
|
461
|
+
@sqlserver_tasks =
|
|
462
|
+
Class.new do
|
|
463
|
+
def create; end
|
|
403
464
|
|
|
465
|
+
def drop; end
|
|
404
466
|
|
|
467
|
+
def purge; end
|
|
468
|
+
|
|
469
|
+
def charset; end
|
|
470
|
+
|
|
471
|
+
def collation; end
|
|
472
|
+
|
|
473
|
+
def structure_dump(*); end
|
|
474
|
+
|
|
475
|
+
def structure_load(*); end
|
|
476
|
+
end.new
|
|
477
|
+
|
|
478
|
+
$stdout, @original_stdout = StringIO.new, $stdout
|
|
479
|
+
$stderr, @original_stderr = StringIO.new, $stderr
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def with_stubbed_new
|
|
483
|
+
ActiveRecord::Tasks::SQLServerDatabaseTasks.stub(:new, @sqlserver_tasks) do
|
|
484
|
+
yield
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
class DatabaseTasksCreateTest < ActiveRecord::TestCase
|
|
490
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
491
|
+
coerce_all_tests!
|
|
492
|
+
|
|
493
|
+
def test_sqlserver_create
|
|
494
|
+
with_stubbed_new do
|
|
495
|
+
assert_called(eval("@sqlserver_tasks"), :create) do
|
|
496
|
+
ActiveRecord::Tasks::DatabaseTasks.create "adapter" => :sqlserver
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
class DatabaseTasksDropTest < ActiveRecord::TestCase
|
|
503
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
504
|
+
coerce_all_tests!
|
|
505
|
+
|
|
506
|
+
def test_sqlserver_drop
|
|
507
|
+
with_stubbed_new do
|
|
508
|
+
assert_called(eval("@sqlserver_tasks"), :drop) do
|
|
509
|
+
ActiveRecord::Tasks::DatabaseTasks.drop "adapter" => :sqlserver
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
class DatabaseTasksPurgeTest < ActiveRecord::TestCase
|
|
516
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
517
|
+
coerce_all_tests!
|
|
518
|
+
|
|
519
|
+
def test_sqlserver_purge
|
|
520
|
+
with_stubbed_new do
|
|
521
|
+
assert_called(eval("@sqlserver_tasks"), :purge) do
|
|
522
|
+
ActiveRecord::Tasks::DatabaseTasks.purge "adapter" => :sqlserver
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
class DatabaseTasksCharsetTest < ActiveRecord::TestCase
|
|
529
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
530
|
+
coerce_all_tests!
|
|
531
|
+
|
|
532
|
+
def test_sqlserver_charset
|
|
533
|
+
with_stubbed_new do
|
|
534
|
+
assert_called(eval("@sqlserver_tasks"), :charset) do
|
|
535
|
+
ActiveRecord::Tasks::DatabaseTasks.charset "adapter" => :sqlserver
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
class DatabaseTasksCollationTest < ActiveRecord::TestCase
|
|
542
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
543
|
+
coerce_all_tests!
|
|
544
|
+
|
|
545
|
+
def test_sqlserver_collation
|
|
546
|
+
with_stubbed_new do
|
|
547
|
+
assert_called(eval("@sqlserver_tasks"), :collation) do
|
|
548
|
+
ActiveRecord::Tasks::DatabaseTasks.collation "adapter" => :sqlserver
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
class DatabaseTasksStructureDumpTest < ActiveRecord::TestCase
|
|
555
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
556
|
+
coerce_all_tests!
|
|
557
|
+
|
|
558
|
+
def test_sqlserver_structure_dump
|
|
559
|
+
with_stubbed_new do
|
|
560
|
+
assert_called_with(
|
|
561
|
+
eval("@sqlserver_tasks"), :structure_dump,
|
|
562
|
+
["awesome-file.sql", nil]
|
|
563
|
+
) do
|
|
564
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :sqlserver }, "awesome-file.sql")
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
class DatabaseTasksStructureLoadTest < ActiveRecord::TestCase
|
|
571
|
+
# Coerce PostgreSQL/SQLite/MySQL tests.
|
|
572
|
+
coerce_all_tests!
|
|
573
|
+
|
|
574
|
+
def test_sqlserver_structure_load
|
|
575
|
+
with_stubbed_new do
|
|
576
|
+
assert_called_with(
|
|
577
|
+
eval("@sqlserver_tasks"),
|
|
578
|
+
:structure_load,
|
|
579
|
+
["awesome-file.sql", nil]
|
|
580
|
+
) do
|
|
581
|
+
ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => :sqlserver }, "awesome-file.sql")
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
end
|
|
405
586
|
|
|
406
|
-
module ActiveRecord
|
|
407
587
|
class DatabaseTasksDumpSchemaCacheTest < ActiveRecord::TestCase
|
|
408
588
|
# Skip this test with /tmp/my_schema_cache.yml path on Windows.
|
|
409
|
-
coerce_tests! :test_dump_schema_cache if RbConfig::CONFIG[
|
|
589
|
+
coerce_tests! :test_dump_schema_cache if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
|
410
590
|
end
|
|
591
|
+
|
|
411
592
|
class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
|
|
412
593
|
# We extend `local_database?` so that common VM IPs can be used.
|
|
413
594
|
coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
|
|
414
595
|
end
|
|
596
|
+
|
|
415
597
|
class DatabaseTasksDropAllTest < ActiveRecord::TestCase
|
|
416
598
|
# We extend `local_database?` so that common VM IPs can be used.
|
|
417
599
|
coerce_tests! :test_ignores_remote_databases, :test_warning_for_remote_databases
|
|
418
600
|
end
|
|
419
601
|
end
|
|
420
602
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
603
|
class DefaultScopingTest < ActiveRecord::TestCase
|
|
425
604
|
# We are not doing order duplicate removal anymore.
|
|
426
605
|
coerce_tests! :test_order_in_default_scope_should_not_prevail
|
|
@@ -434,16 +613,13 @@ class DefaultScopingTest < ActiveRecord::TestCase
|
|
|
434
613
|
end
|
|
435
614
|
end
|
|
436
615
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
require 'models/post'
|
|
441
|
-
require 'models/subscriber'
|
|
616
|
+
require "models/post"
|
|
617
|
+
require "models/subscriber"
|
|
442
618
|
class EachTest < ActiveRecord::TestCase
|
|
443
619
|
# Quoting in tests does not cope with bracket quoting.
|
|
444
620
|
coerce_tests! :test_find_in_batches_should_quote_batch_order
|
|
445
621
|
def test_find_in_batches_should_quote_batch_order_coerced
|
|
446
|
-
|
|
622
|
+
Post.connection
|
|
447
623
|
assert_sql(/ORDER BY \[posts\]\.\[id\]/) do
|
|
448
624
|
Post.find_in_batches(:batch_size => 1) do |batch|
|
|
449
625
|
assert_kind_of Array, batch
|
|
@@ -455,7 +631,7 @@ class EachTest < ActiveRecord::TestCase
|
|
|
455
631
|
# Quoting in tests does not cope with bracket quoting.
|
|
456
632
|
coerce_tests! :test_in_batches_should_quote_batch_order
|
|
457
633
|
def test_in_batches_should_quote_batch_order_coerced
|
|
458
|
-
|
|
634
|
+
Post.connection
|
|
459
635
|
assert_sql(/ORDER BY \[posts\]\.\[id\]/) do
|
|
460
636
|
Post.in_batches(of: 1) do |relation|
|
|
461
637
|
assert_kind_of ActiveRecord::Relation, relation
|
|
@@ -465,9 +641,6 @@ class EachTest < ActiveRecord::TestCase
|
|
|
465
641
|
end
|
|
466
642
|
end
|
|
467
643
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
644
|
class EagerAssociationTest < ActiveRecord::TestCase
|
|
472
645
|
# Use LEN() vs length() function.
|
|
473
646
|
coerce_tests! :test_count_with_include
|
|
@@ -479,14 +652,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|
|
479
652
|
coerce_tests! %r{including association based on sql condition and no database column}
|
|
480
653
|
end
|
|
481
654
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
require 'models/topic'
|
|
655
|
+
require "models/topic"
|
|
486
656
|
class FinderTest < ActiveRecord::TestCase
|
|
657
|
+
# We have implicit ordering, via FETCH.
|
|
487
658
|
coerce_tests! %r{doesn't have implicit ordering},
|
|
488
|
-
:test_find_doesnt_have_implicit_ordering
|
|
659
|
+
:test_find_doesnt_have_implicit_ordering
|
|
489
660
|
|
|
661
|
+
# Square brackets around column name
|
|
490
662
|
coerce_tests! :test_exists_does_not_select_columns_without_alias
|
|
491
663
|
def test_exists_does_not_select_columns_without_alias_coerced
|
|
492
664
|
assert_sql(/SELECT\s+1 AS one FROM \[topics\].*OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.*@0 = 1/i) do
|
|
@@ -494,6 +666,7 @@ class FinderTest < ActiveRecord::TestCase
|
|
|
494
666
|
end
|
|
495
667
|
end
|
|
496
668
|
|
|
669
|
+
# Assert SQL Server limit implementation
|
|
497
670
|
coerce_tests! :test_take_and_first_and_last_with_integer_should_use_sql_limit
|
|
498
671
|
def test_take_and_first_and_last_with_integer_should_use_sql_limit_coerced
|
|
499
672
|
assert_sql(/OFFSET 0 ROWS FETCH NEXT @0 ROWS ONLY.* @0 = 3/) { Topic.take(3).entries }
|
|
@@ -507,7 +680,7 @@ class FinderTest < ActiveRecord::TestCase
|
|
|
507
680
|
# Can not use array condition due to not finding right type and hence fractional second quoting.
|
|
508
681
|
coerce_tests! :test_condition_utc_time_interpolation_with_default_timezone_local
|
|
509
682
|
def test_condition_utc_time_interpolation_with_default_timezone_local_coerced
|
|
510
|
-
with_env_tz
|
|
683
|
+
with_env_tz "America/New_York" do
|
|
511
684
|
with_timezone_config default: :local do
|
|
512
685
|
topic = Topic.first
|
|
513
686
|
assert_equal topic, Topic.where(written_on: topic.written_on.getutc).first
|
|
@@ -518,7 +691,7 @@ class FinderTest < ActiveRecord::TestCase
|
|
|
518
691
|
# Can not use array condition due to not finding right type and hence fractional second quoting.
|
|
519
692
|
coerce_tests! :test_condition_local_time_interpolation_with_default_timezone_utc
|
|
520
693
|
def test_condition_local_time_interpolation_with_default_timezone_utc_coerced
|
|
521
|
-
with_env_tz
|
|
694
|
+
with_env_tz "America/New_York" do
|
|
522
695
|
with_timezone_config default: :utc do
|
|
523
696
|
topic = Topic.first
|
|
524
697
|
assert_equal topic, Topic.where(written_on: topic.written_on.getlocal).first
|
|
@@ -527,9 +700,6 @@ class FinderTest < ActiveRecord::TestCase
|
|
|
527
700
|
end
|
|
528
701
|
end
|
|
529
702
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
703
|
module ActiveRecord
|
|
534
704
|
class Migration
|
|
535
705
|
class ForeignKeyTest < ActiveRecord::TestCase
|
|
@@ -547,90 +717,103 @@ module ActiveRecord
|
|
|
547
717
|
end
|
|
548
718
|
end
|
|
549
719
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
720
|
class HasOneAssociationsTest < ActiveRecord::TestCase
|
|
554
721
|
# We use OFFSET/FETCH vs TOP. So we always have an order.
|
|
555
722
|
coerce_tests! :test_has_one_does_not_use_order_by
|
|
556
|
-
end
|
|
557
|
-
|
|
558
723
|
|
|
724
|
+
# Asserted SQL to get one row different from original test.
|
|
725
|
+
coerce_tests! :test_has_one
|
|
726
|
+
def test_has_one_coerced
|
|
727
|
+
firm = companies(:first_firm)
|
|
728
|
+
first_account = Account.find(1)
|
|
729
|
+
assert_sql(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
|
|
730
|
+
assert_equal first_account, firm.account
|
|
731
|
+
assert_equal first_account.credit_limit, firm.account.credit_limit
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
end
|
|
559
735
|
|
|
736
|
+
class HasOneThroughAssociationsTest < ActiveRecord::TestCase
|
|
737
|
+
# Asserted SQL to get one row different from original test.
|
|
738
|
+
coerce_tests! :test_has_one_through_executes_limited_query
|
|
739
|
+
def test_has_one_through_executes_limited_query_coerced
|
|
740
|
+
boring_club = clubs(:boring_club)
|
|
741
|
+
assert_sql(/FETCH NEXT @(\d) ROWS ONLY(.)*@\1 = 1/) do
|
|
742
|
+
assert_equal boring_club, @member.general_club
|
|
743
|
+
end
|
|
744
|
+
end
|
|
745
|
+
end
|
|
560
746
|
|
|
561
|
-
require
|
|
747
|
+
require "models/company"
|
|
562
748
|
class InheritanceTest < ActiveRecord::TestCase
|
|
749
|
+
# Rails test required inserting to a identity column.
|
|
563
750
|
coerce_tests! :test_a_bad_type_column
|
|
564
751
|
def test_a_bad_type_column_coerced
|
|
565
|
-
Company.connection.with_identity_insert_enabled(
|
|
752
|
+
Company.connection.with_identity_insert_enabled("companies") do
|
|
566
753
|
Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
|
|
567
754
|
end
|
|
568
755
|
assert_raise(ActiveRecord::SubclassNotFound) { Company.find(100) }
|
|
569
756
|
end
|
|
570
757
|
|
|
758
|
+
# Use Square brackets around column name
|
|
571
759
|
coerce_tests! :test_eager_load_belongs_to_primary_key_quoting
|
|
572
760
|
def test_eager_load_belongs_to_primary_key_quoting_coerced
|
|
573
|
-
|
|
761
|
+
Account.connection
|
|
574
762
|
assert_sql(/\[companies\]\.\[id\] = @0.* @0 = 1/) do
|
|
575
763
|
Account.all.merge!(:includes => :firm).find(1)
|
|
576
764
|
end
|
|
577
765
|
end
|
|
578
766
|
end
|
|
579
767
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
768
|
class LeftOuterJoinAssociationTest < ActiveRecord::TestCase
|
|
584
769
|
# Uses || operator in SQL. Just trust core gets value out of this test.
|
|
585
770
|
coerce_tests! :test_does_not_override_select
|
|
586
771
|
end
|
|
587
772
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
class NamedScopingTest < ActiveRecord::TestCase
|
|
592
|
-
# This works now because we add an `order(:id)` sort to break the order tie for deterministic results.
|
|
593
|
-
coerce_tests! :test_scopes_honor_current_scopes_from_when_defined
|
|
594
|
-
def test_scopes_honor_current_scopes_from_when_defined_coerced
|
|
595
|
-
assert !Post.ranked_by_comments.order(:id).limit_by(5).empty?
|
|
596
|
-
assert !authors(:david).posts.ranked_by_comments.order(:id).limit_by(5).empty?
|
|
597
|
-
assert_not_equal Post.ranked_by_comments.order(:id).limit_by(5), authors(:david).posts.ranked_by_comments.order(:id).limit_by(5)
|
|
598
|
-
assert_not_equal Post.order(:id).top(5), authors(:david).posts.order(:id).top(5)
|
|
599
|
-
# Oracle sometimes sorts differently if WHERE condition is changed
|
|
600
|
-
assert_equal authors(:david).posts.ranked_by_comments.limit_by(5).to_a.sort_by(&:id), authors(:david).posts.top(5).to_a.sort_by(&:id)
|
|
601
|
-
assert_equal Post.ranked_by_comments.limit_by(5), Post.top(5)
|
|
602
|
-
end
|
|
603
|
-
end
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
require 'models/developer'
|
|
609
|
-
require 'models/computer'
|
|
773
|
+
require "models/developer"
|
|
774
|
+
require "models/computer"
|
|
610
775
|
class NestedRelationScopingTest < ActiveRecord::TestCase
|
|
776
|
+
# Assert SQL Server limit implementation
|
|
611
777
|
coerce_tests! :test_merge_options
|
|
612
778
|
def test_merge_options_coerced
|
|
613
|
-
Developer.where(
|
|
779
|
+
Developer.where("salary = 80000").scoping do
|
|
614
780
|
Developer.limit(10).scoping do
|
|
615
781
|
devs = Developer.all
|
|
616
782
|
sql = devs.to_sql
|
|
617
|
-
assert_match
|
|
618
|
-
assert_match
|
|
783
|
+
assert_match "(salary = 80000)", sql
|
|
784
|
+
assert_match "FETCH NEXT 10 ROWS ONLY", sql
|
|
619
785
|
end
|
|
620
786
|
end
|
|
621
787
|
end
|
|
622
788
|
end
|
|
623
789
|
|
|
790
|
+
require "models/topic"
|
|
791
|
+
class PersistenceTest < ActiveRecord::TestCase
|
|
792
|
+
# Rails test required updating a identity column.
|
|
793
|
+
coerce_tests! :test_update_columns_changing_id
|
|
624
794
|
|
|
795
|
+
# Rails test required updating a identity column.
|
|
796
|
+
coerce_tests! :test_update
|
|
797
|
+
def test_update_coerced
|
|
798
|
+
topic = Topic.find(1)
|
|
799
|
+
assert_not_predicate topic, :approved?
|
|
800
|
+
assert_equal "The First Topic", topic.title
|
|
625
801
|
|
|
802
|
+
topic.update("approved" => true, "title" => "The First Topic Updated")
|
|
803
|
+
topic.reload
|
|
804
|
+
assert_predicate topic, :approved?
|
|
805
|
+
assert_equal "The First Topic Updated", topic.title
|
|
626
806
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
807
|
+
topic.update(approved: false, title: "The First Topic")
|
|
808
|
+
topic.reload
|
|
809
|
+
assert_not_predicate topic, :approved?
|
|
810
|
+
assert_equal "The First Topic", topic.title
|
|
811
|
+
end
|
|
812
|
+
end
|
|
632
813
|
|
|
633
|
-
|
|
814
|
+
require "models/author"
|
|
815
|
+
class UpdateAllTest < ActiveRecord::TestCase
|
|
816
|
+
# Rails test required updating a identity column.
|
|
634
817
|
coerce_tests! :test_update_all_doesnt_ignore_order
|
|
635
818
|
def test_update_all_doesnt_ignore_order_coerced
|
|
636
819
|
david, mary = authors(:david), authors(:mary)
|
|
@@ -638,81 +821,80 @@ class PersistenceTest < ActiveRecord::TestCase
|
|
|
638
821
|
_(mary.id).must_equal 2
|
|
639
822
|
_(david.name).wont_equal mary.name
|
|
640
823
|
assert_sql(/UPDATE.*\(SELECT \[authors\].\[id\] FROM \[authors\].*ORDER BY \[authors\].\[id\]/i) do
|
|
641
|
-
Author.where(
|
|
824
|
+
Author.where("[id] > 1").order(:id).update_all(name: "Test")
|
|
642
825
|
end
|
|
643
|
-
_(david.reload.name).must_equal
|
|
644
|
-
_(mary.reload.name).must_equal
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
# We can not UPDATE identity columns.
|
|
648
|
-
coerce_tests! :test_update_attributes
|
|
649
|
-
def test_update_attributes_coerced
|
|
650
|
-
topic = Topic.find(1)
|
|
651
|
-
assert !topic.approved?
|
|
652
|
-
assert_equal "The First Topic", topic.title
|
|
653
|
-
topic.update_attributes("approved" => true, "title" => "The First Topic Updated")
|
|
654
|
-
topic.reload
|
|
655
|
-
assert topic.approved?
|
|
656
|
-
assert_equal "The First Topic Updated", topic.title
|
|
657
|
-
topic.update_attributes(approved: false, title: "The First Topic")
|
|
658
|
-
topic.reload
|
|
659
|
-
assert !topic.approved?
|
|
660
|
-
assert_equal "The First Topic", topic.title
|
|
661
|
-
# SQLServer: Here is where it breaks down. No exceptions.
|
|
662
|
-
# assert_raise(ActiveRecord::RecordNotUnique, ActiveRecord::StatementInvalid) do
|
|
663
|
-
# topic.update_attributes(id: 3, title: "Hm is it possible?")
|
|
664
|
-
# end
|
|
665
|
-
# assert_not_equal "Hm is it possible?", Topic.find(3).title
|
|
666
|
-
# topic.update_attributes(id: 1234)
|
|
667
|
-
# assert_nothing_raised { topic.reload }
|
|
668
|
-
# assert_equal topic.title, Topic.find(1234).title
|
|
826
|
+
_(david.reload.name).must_equal "David"
|
|
827
|
+
_(mary.reload.name).must_equal "Test"
|
|
669
828
|
end
|
|
670
829
|
end
|
|
671
830
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
require 'models/topic'
|
|
831
|
+
require "models/topic"
|
|
676
832
|
module ActiveRecord
|
|
677
833
|
class PredicateBuilderTest < ActiveRecord::TestCase
|
|
834
|
+
# Same as original test except string has `N` prefix to indicate unicode string.
|
|
678
835
|
coerce_tests! :test_registering_new_handlers
|
|
679
836
|
def test_registering_new_handlers_coerced
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
837
|
+
assert_match %r{#{Regexp.escape(topic_title)} ~ N'rails'}i, Topic.where(title: /rails/).to_sql
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
# Same as original test except string has `N` prefix to indicate unicode string.
|
|
841
|
+
coerce_tests! :test_registering_new_handlers_for_association
|
|
842
|
+
def test_registering_new_handlers_for_association_coerced
|
|
843
|
+
assert_match %r{#{Regexp.escape(topic_title)} ~ N'rails'}i, Reply.joins(:topic).where(topics: { title: /rails/ }).to_sql
|
|
686
844
|
end
|
|
687
845
|
end
|
|
688
846
|
end
|
|
689
847
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
848
|
class PrimaryKeysTest < ActiveRecord::TestCase
|
|
694
|
-
#
|
|
695
|
-
# but as far as I can tell, this is only one for us anyway.
|
|
849
|
+
# SQL Server does not have query for release_savepoint
|
|
696
850
|
coerce_tests! :test_create_without_primary_key_no_extra_query
|
|
851
|
+
def test_create_without_primary_key_no_extra_query_coerced
|
|
852
|
+
klass = Class.new(ActiveRecord::Base) do
|
|
853
|
+
self.table_name = "dashboards"
|
|
854
|
+
end
|
|
855
|
+
klass.create! # warmup schema cache
|
|
856
|
+
assert_queries(2, ignore_none: true) { klass.create! }
|
|
857
|
+
end
|
|
697
858
|
end
|
|
698
859
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
require 'models/task'
|
|
860
|
+
require "models/task"
|
|
703
861
|
class QueryCacheTest < ActiveRecord::TestCase
|
|
862
|
+
# SQL Server adapter not in list of supported adapters in original test.
|
|
704
863
|
coerce_tests! :test_cache_does_not_wrap_results_in_arrays
|
|
705
864
|
def test_cache_does_not_wrap_results_in_arrays_coerced
|
|
706
865
|
Task.cache do
|
|
707
|
-
|
|
866
|
+
assert_equal 2, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
|
|
708
867
|
end
|
|
709
868
|
end
|
|
710
|
-
end
|
|
711
869
|
|
|
870
|
+
# Same as original test except that we expect one query to be performed to retrieve the table's primary key.
|
|
871
|
+
# When we generate the SQL for the `find` it includes ordering on the primary key. If we reset the column
|
|
872
|
+
# information then the primary key needs to be retrieved from the database again to generate the SQL causing the
|
|
873
|
+
# original test's `assert_no_queries` assertion to fail. Assert that the query was to get the primary key.
|
|
874
|
+
coerce_tests! :test_query_cached_even_when_types_are_reset
|
|
875
|
+
def test_query_cached_even_when_types_are_reset_coerced
|
|
876
|
+
Task.cache do
|
|
877
|
+
# Warm the cache
|
|
878
|
+
Task.find(1)
|
|
879
|
+
|
|
880
|
+
# Preload the type cache again (so we don't have those queries issued during our assertions)
|
|
881
|
+
Task.connection.send(:reload_type_map)
|
|
712
882
|
|
|
883
|
+
# Clear places where type information is cached
|
|
884
|
+
Task.reset_column_information
|
|
885
|
+
Task.initialize_find_by_cache
|
|
886
|
+
Task.define_attribute_methods
|
|
713
887
|
|
|
888
|
+
assert_queries(1, ignore_none: true) do
|
|
889
|
+
Task.find(1)
|
|
890
|
+
end
|
|
714
891
|
|
|
715
|
-
|
|
892
|
+
assert_includes ActiveRecord::SQLCounter.log_all.first, "TC.CONSTRAINT_TYPE = N''PRIMARY KEY''"
|
|
893
|
+
end
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
require "models/post"
|
|
716
898
|
class RelationTest < ActiveRecord::TestCase
|
|
717
899
|
# Use LEN vs LENGTH function.
|
|
718
900
|
coerce_tests! :test_reverse_order_with_function
|
|
@@ -733,6 +915,26 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
733
915
|
# We have implicit ordering, via FETCH.
|
|
734
916
|
coerce_tests! %r{doesn't have implicit ordering}
|
|
735
917
|
|
|
918
|
+
# We have implicit ordering, via FETCH.
|
|
919
|
+
coerce_tests! :test_reorder_with_take
|
|
920
|
+
def test_reorder_with_take_coerced
|
|
921
|
+
sql_log = capture_sql do
|
|
922
|
+
assert Post.order(:title).reorder(nil).take
|
|
923
|
+
end
|
|
924
|
+
assert sql_log.none? { |sql| /order by [posts].[title]/i.match?(sql) }, "ORDER BY title was used in the query: #{sql_log}"
|
|
925
|
+
assert sql_log.all? { |sql| /order by \[posts\]\.\[id\]/i.match?(sql) }, "default ORDER BY ID was not used in the query: #{sql_log}"
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
# We have implicit ordering, via FETCH.
|
|
929
|
+
coerce_tests! :test_reorder_with_first
|
|
930
|
+
def test_reorder_with_first_coerced
|
|
931
|
+
sql_log = capture_sql do
|
|
932
|
+
assert Post.order(:title).reorder(nil).first
|
|
933
|
+
end
|
|
934
|
+
assert sql_log.none? { |sql| /order by [posts].[title]/i.match?(sql) }, "ORDER BY title was used in the query: #{sql_log}"
|
|
935
|
+
assert sql_log.all? { |sql| /order by \[posts\]\.\[id\]/i.match?(sql) }, "default ORDER BY ID was not used in the query: #{sql_log}"
|
|
936
|
+
end
|
|
937
|
+
|
|
736
938
|
# We are not doing order duplicate removal anymore.
|
|
737
939
|
coerce_tests! :test_order_using_scoping
|
|
738
940
|
|
|
@@ -756,17 +958,17 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
756
958
|
# so we are skipping all together.
|
|
757
959
|
coerce_tests! :test_empty_complex_chained_relations
|
|
758
960
|
|
|
759
|
-
# Can't apply offset
|
|
961
|
+
# Can't apply offset without ORDER
|
|
760
962
|
coerce_tests! %r{using a custom table affects the wheres}
|
|
761
|
-
test
|
|
963
|
+
test "using a custom table affects the wheres coerced" do
|
|
762
964
|
post = posts(:welcome)
|
|
763
965
|
|
|
764
966
|
assert_equal post, custom_post_relation.where!(title: post.title).order(:id).take
|
|
765
967
|
end
|
|
766
968
|
|
|
767
|
-
# Can't apply offset
|
|
969
|
+
# Can't apply offset without ORDER
|
|
768
970
|
coerce_tests! %r{using a custom table with joins affects the joins}
|
|
769
|
-
test
|
|
971
|
+
test "using a custom table with joins affects the joins coerced" do
|
|
770
972
|
post = posts(:welcome)
|
|
771
973
|
|
|
772
974
|
assert_equal post, custom_post_relation.joins(:author).where!(title: post.title).order(:id).take
|
|
@@ -780,45 +982,31 @@ class RelationTest < ActiveRecord::TestCase
|
|
|
780
982
|
end
|
|
781
983
|
end
|
|
782
984
|
|
|
783
|
-
|
|
784
|
-
coerce_tests! :test_relation_merging_with_merged_symbol_joins_is_aliased
|
|
785
|
-
def test_relation_merging_with_merged_symbol_joins_is_aliased__coerced
|
|
786
|
-
categorizations_with_authors = Categorization.joins(:author)
|
|
787
|
-
queries = capture_sql { Post.joins(:author, :categorizations).merge(Author.select(:id)).merge(categorizations_with_authors).to_a }
|
|
788
|
-
|
|
789
|
-
nb_inner_join = queries.sum { |sql| sql.scan(/INNER\s+JOIN/i).size }
|
|
790
|
-
assert_equal 3, nb_inner_join, "Wrong amount of INNER JOIN in query"
|
|
791
|
-
|
|
792
|
-
# using `\W` as the column separator
|
|
793
|
-
query_matches = queries.any? do |sql|
|
|
794
|
-
%r[INNER\s+JOIN\s+#{Regexp.escape(Author.quoted_table_name)}\s+\Wauthors_categorizations\W]i.match?(sql)
|
|
795
|
-
end
|
|
796
|
-
|
|
797
|
-
assert query_matches, "Should be aliasing the child INNER JOINs in query"
|
|
798
|
-
end
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
require 'models/post'
|
|
985
|
+
require "models/post"
|
|
805
986
|
class SanitizeTest < ActiveRecord::TestCase
|
|
987
|
+
# Use nvarchar string (N'') in assert
|
|
806
988
|
coerce_tests! :test_sanitize_sql_like_example_use_case
|
|
807
989
|
def test_sanitize_sql_like_example_use_case_coerced
|
|
808
990
|
searchable_post = Class.new(Post) do
|
|
809
|
-
def self.
|
|
810
|
-
where("title LIKE ?", sanitize_sql_like(term,
|
|
991
|
+
def self.search_as_method(term)
|
|
992
|
+
where("title LIKE ?", sanitize_sql_like(term, "!"))
|
|
811
993
|
end
|
|
994
|
+
|
|
995
|
+
scope :search_as_scope, ->(term) {
|
|
996
|
+
where("title LIKE ?", sanitize_sql_like(term, "!"))
|
|
997
|
+
}
|
|
812
998
|
end
|
|
813
|
-
|
|
814
|
-
|
|
999
|
+
|
|
1000
|
+
assert_sql(/LIKE N'20!% !_reduction!_!!'/) do
|
|
1001
|
+
searchable_post.search_as_method("20% _reduction_!").to_a
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
assert_sql(/LIKE N'20!% !_reduction!_!!'/) do
|
|
1005
|
+
searchable_post.search_as_scope("20% _reduction_!").to_a
|
|
815
1006
|
end
|
|
816
1007
|
end
|
|
817
1008
|
end
|
|
818
1009
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
1010
|
class SchemaDumperTest < ActiveRecord::TestCase
|
|
823
1011
|
# We have precision to 38.
|
|
824
1012
|
coerce_tests! :test_schema_dump_keeps_large_precision_integer_columns_as_decimal
|
|
@@ -850,19 +1038,14 @@ class SchemaDumperDefaultsTest < ActiveRecord::TestCase
|
|
|
850
1038
|
coerce_tests! :test_schema_dump_defaults_with_universally_supported_types
|
|
851
1039
|
end
|
|
852
1040
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
1041
|
class TestAdapterWithInvalidConnection < ActiveRecord::TestCase
|
|
857
1042
|
# We trust Rails on this since we do not want to install mysql.
|
|
858
1043
|
coerce_tests! %r{inspect on Model class does not raise}
|
|
859
1044
|
end
|
|
860
1045
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
require 'models/topic'
|
|
1046
|
+
require "models/topic"
|
|
865
1047
|
class TransactionTest < ActiveRecord::TestCase
|
|
1048
|
+
# SQL Server does not have query for release_savepoint
|
|
866
1049
|
coerce_tests! :test_releasing_named_savepoints
|
|
867
1050
|
def test_releasing_named_savepoints_coerced
|
|
868
1051
|
Topic.transaction do
|
|
@@ -874,10 +1057,7 @@ class TransactionTest < ActiveRecord::TestCase
|
|
|
874
1057
|
end
|
|
875
1058
|
end
|
|
876
1059
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
require 'models/tag'
|
|
1060
|
+
require "models/tag"
|
|
881
1061
|
class TransactionIsolationTest < ActiveRecord::TestCase
|
|
882
1062
|
# SQL Server will lock the table for counts even when both
|
|
883
1063
|
# connections are `READ COMMITTED`. So we bypass with `READPAST`.
|
|
@@ -887,7 +1067,7 @@ class TransactionIsolationTest < ActiveRecord::TestCase
|
|
|
887
1067
|
assert_equal 0, Tag.count
|
|
888
1068
|
Tag2.transaction do
|
|
889
1069
|
Tag2.create
|
|
890
|
-
assert_equal 0, Tag.lock(
|
|
1070
|
+
assert_equal 0, Tag.lock("WITH(READPAST)").count
|
|
891
1071
|
end
|
|
892
1072
|
end
|
|
893
1073
|
assert_equal 1, Tag.count
|
|
@@ -897,10 +1077,7 @@ class TransactionIsolationTest < ActiveRecord::TestCase
|
|
|
897
1077
|
coerce_tests! %r{repeatable read}
|
|
898
1078
|
end
|
|
899
1079
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
require 'models/book'
|
|
1080
|
+
require "models/book"
|
|
904
1081
|
class ViewWithPrimaryKeyTest < ActiveRecord::TestCase
|
|
905
1082
|
# We have a few view tables. use includes vs equality.
|
|
906
1083
|
coerce_tests! :test_views
|
|
@@ -912,9 +1089,10 @@ class ViewWithPrimaryKeyTest < ActiveRecord::TestCase
|
|
|
912
1089
|
coerce_tests! :test_does_not_assume_id_column_as_primary_key
|
|
913
1090
|
def test_does_not_assume_id_column_as_primary_key_coerced
|
|
914
1091
|
model = Class.new(ActiveRecord::Base) { self.table_name = "ebooks" }
|
|
915
|
-
assert_equal
|
|
1092
|
+
assert_equal "id", model.primary_key
|
|
916
1093
|
end
|
|
917
1094
|
end
|
|
1095
|
+
|
|
918
1096
|
class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
|
|
919
1097
|
# We have a few view tables. use includes vs equality.
|
|
920
1098
|
coerce_tests! :test_views
|
|
@@ -923,23 +1101,17 @@ class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
|
|
|
923
1101
|
end
|
|
924
1102
|
end
|
|
925
1103
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
require 'models/author'
|
|
1104
|
+
require "models/author"
|
|
930
1105
|
class YamlSerializationTest < ActiveRecord::TestCase
|
|
931
1106
|
coerce_tests! :test_types_of_virtual_columns_are_not_changed_on_round_trip
|
|
932
1107
|
def test_types_of_virtual_columns_are_not_changed_on_round_trip_coerced
|
|
933
|
-
author = Author.select(
|
|
1108
|
+
author = Author.select("authors.*, 5 as posts_count").first
|
|
934
1109
|
dumped = YAML.load(YAML.dump(author))
|
|
935
1110
|
assert_equal 5, author.posts_count
|
|
936
1111
|
assert_equal 5, dumped.posts_count
|
|
937
1112
|
end
|
|
938
1113
|
end
|
|
939
1114
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
1115
|
class DateTimePrecisionTest < ActiveRecord::TestCase
|
|
944
1116
|
# Original test had `7` which we support vs `8` which we use.
|
|
945
1117
|
coerce_tests! :test_invalid_datetime_precision_raises_error
|
|
@@ -955,7 +1127,7 @@ class DateTimePrecisionTest < ActiveRecord::TestCase
|
|
|
955
1127
|
coerce_tests! :test_datetime_precision_is_truncated_on_assignment
|
|
956
1128
|
def test_datetime_precision_is_truncated_on_assignment_coerced
|
|
957
1129
|
@connection.create_table(:foos, force: true)
|
|
958
|
-
@connection.add_column :foos, :created_at,
|
|
1130
|
+
@connection.add_column :foos, :created_at, :datetime, precision: 0
|
|
959
1131
|
@connection.add_column :foos, :updated_at, :datetime, precision: 6
|
|
960
1132
|
|
|
961
1133
|
time = ::Time.now.change(nsec: 123456789)
|
|
@@ -972,8 +1144,6 @@ class DateTimePrecisionTest < ActiveRecord::TestCase
|
|
|
972
1144
|
end
|
|
973
1145
|
end
|
|
974
1146
|
|
|
975
|
-
|
|
976
|
-
|
|
977
1147
|
class TimePrecisionTest < ActiveRecord::TestCase
|
|
978
1148
|
# datetime is rounded to increments of .000, .003, or .007 seconds
|
|
979
1149
|
coerce_tests! :test_time_precision_is_truncated_on_assignment
|
|
@@ -994,9 +1164,10 @@ class TimePrecisionTest < ActiveRecord::TestCase
|
|
|
994
1164
|
assert_equal 0, foo.start.nsec
|
|
995
1165
|
assert_equal 123457000, foo.finish.nsec
|
|
996
1166
|
end
|
|
997
|
-
end
|
|
998
|
-
|
|
999
1167
|
|
|
1168
|
+
# SQL Server uses default precision for time.
|
|
1169
|
+
coerce_tests! :test_no_time_precision_isnt_truncated_on_assignment
|
|
1170
|
+
end
|
|
1000
1171
|
|
|
1001
1172
|
class DefaultNumbersTest < ActiveRecord::TestCase
|
|
1002
1173
|
# We do better with native types and do not return strings for everything.
|
|
@@ -1006,16 +1177,23 @@ class DefaultNumbersTest < ActiveRecord::TestCase
|
|
|
1006
1177
|
assert_equal 7, record.positive_integer
|
|
1007
1178
|
assert_equal 7, record.positive_integer_before_type_cast
|
|
1008
1179
|
end
|
|
1180
|
+
|
|
1181
|
+
# We do better with native types and do not return strings for everything.
|
|
1009
1182
|
coerce_tests! :test_default_negative_integer
|
|
1010
1183
|
def test_default_negative_integer_coerced
|
|
1011
1184
|
record = DefaultNumber.new
|
|
1012
1185
|
assert_equal -5, record.negative_integer
|
|
1013
1186
|
assert_equal -5, record.negative_integer_before_type_cast
|
|
1014
1187
|
end
|
|
1015
|
-
end
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
1188
|
|
|
1189
|
+
# We do better with native types and do not return strings for everything.
|
|
1190
|
+
coerce_tests! :test_default_decimal_number
|
|
1191
|
+
def test_default_decimal_number_coerced
|
|
1192
|
+
record = DefaultNumber.new
|
|
1193
|
+
assert_equal BigDecimal("2.78"), record.decimal_number
|
|
1194
|
+
assert_equal 2.78, record.decimal_number_before_type_cast
|
|
1195
|
+
end
|
|
1196
|
+
end
|
|
1019
1197
|
|
|
1020
1198
|
module ActiveRecord
|
|
1021
1199
|
class CollectionCacheKeyTest < ActiveRecord::TestCase
|
|
@@ -1024,40 +1202,59 @@ module ActiveRecord
|
|
|
1024
1202
|
end
|
|
1025
1203
|
end
|
|
1026
1204
|
|
|
1205
|
+
module ActiveRecord
|
|
1206
|
+
class CacheKeyTest < ActiveRecord::TestCase
|
|
1207
|
+
# Like Mysql2 and PostgreSQL, SQL Server doesn't return a string value for updated_at. In the Rails tests
|
|
1208
|
+
# the tests are skipped if adapter is Mysql2 or PostgreSQL.
|
|
1209
|
+
coerce_tests! %r{cache_version is the same when it comes from the DB or from the user}
|
|
1210
|
+
coerce_tests! %r{cache_version does NOT call updated_at when value is from the database}
|
|
1211
|
+
coerce_tests! %r{cache_version does not truncate zeros when timestamp ends in zeros}
|
|
1212
|
+
end
|
|
1213
|
+
end
|
|
1027
1214
|
|
|
1028
|
-
|
|
1029
|
-
|
|
1215
|
+
require "models/book"
|
|
1030
1216
|
module ActiveRecord
|
|
1031
1217
|
class StatementCacheTest < ActiveRecord::TestCase
|
|
1032
1218
|
# Getting random failures.
|
|
1033
1219
|
coerce_tests! :test_find_does_not_use_statement_cache_if_table_name_is_changed
|
|
1034
|
-
end
|
|
1035
|
-
end
|
|
1036
|
-
|
|
1037
1220
|
|
|
1221
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
|
1222
|
+
coerce_tests! :test_statement_cache_values_differ
|
|
1223
|
+
def test_statement_cache_values_differ_coerced
|
|
1224
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
|
1038
1225
|
|
|
1226
|
+
original_test_statement_cache_values_differ
|
|
1227
|
+
ensure
|
|
1228
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
|
1229
|
+
end
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1039
1232
|
|
|
1040
1233
|
module ActiveRecord
|
|
1041
1234
|
module ConnectionAdapters
|
|
1042
1235
|
class SchemaCacheTest < ActiveRecord::TestCase
|
|
1043
1236
|
private
|
|
1237
|
+
|
|
1044
1238
|
# We need to give the full path for this to work.
|
|
1045
1239
|
def schema_dump_path
|
|
1046
|
-
File.join ARTest::SQLServer.root_activerecord,
|
|
1240
|
+
File.join ARTest::SQLServer.root_activerecord, "test/assets/schema_dump_5_1.yml"
|
|
1047
1241
|
end
|
|
1048
1242
|
end
|
|
1049
1243
|
end
|
|
1050
1244
|
end
|
|
1051
1245
|
|
|
1052
1246
|
class UnsafeRawSqlTest < ActiveRecord::TestCase
|
|
1053
|
-
|
|
1054
|
-
|
|
1247
|
+
# Use LEN() vs length() function.
|
|
1248
|
+
coerce_tests! %r{order: always allows Arel}
|
|
1249
|
+
test "order: always allows Arel" do
|
|
1055
1250
|
ids_depr = with_unsafe_raw_sql_deprecated { Post.order(Arel.sql("len(title)")).pluck(:title) }
|
|
1056
1251
|
ids_disabled = with_unsafe_raw_sql_disabled { Post.order(Arel.sql("len(title)")).pluck(:title) }
|
|
1057
1252
|
|
|
1058
1253
|
assert_equal ids_depr, ids_disabled
|
|
1059
1254
|
end
|
|
1060
1255
|
|
|
1256
|
+
# Use LEN() vs length() function.
|
|
1257
|
+
coerce_tests! %r{pluck: always allows Arel}
|
|
1061
1258
|
test "pluck: always allows Arel" do
|
|
1062
1259
|
values_depr = with_unsafe_raw_sql_deprecated { Post.includes(:comments).pluck(:title, Arel.sql("len(title)")) }
|
|
1063
1260
|
values_disabled = with_unsafe_raw_sql_disabled { Post.includes(:comments).pluck(:title, Arel.sql("len(title)")) }
|
|
@@ -1065,74 +1262,19 @@ class UnsafeRawSqlTest < ActiveRecord::TestCase
|
|
|
1065
1262
|
assert_equal values_depr, values_disabled
|
|
1066
1263
|
end
|
|
1067
1264
|
|
|
1068
|
-
|
|
1069
|
-
coerce_tests! %r{order: disallows invalid Array arguments}
|
|
1070
|
-
test "order: disallows invalid Array arguments" do
|
|
1071
|
-
with_unsafe_raw_sql_disabled do
|
|
1072
|
-
assert_raises(ActiveRecord::UnknownAttributeReference) do
|
|
1073
|
-
Post.order(["author_id", "len(title)"]).pluck(:id)
|
|
1074
|
-
end
|
|
1075
|
-
end
|
|
1076
|
-
end
|
|
1077
|
-
|
|
1265
|
+
# Use LEN() vs length() function.
|
|
1078
1266
|
coerce_tests! %r{order: allows valid Array arguments}
|
|
1079
1267
|
test "order: allows valid Array arguments" do
|
|
1080
1268
|
ids_expected = Post.order(Arel.sql("author_id, len(title)")).pluck(:id)
|
|
1081
1269
|
|
|
1082
|
-
ids_depr = with_unsafe_raw_sql_deprecated { Post.order(["author_id",
|
|
1083
|
-
ids_disabled = with_unsafe_raw_sql_disabled { Post.order(["author_id",
|
|
1270
|
+
ids_depr = with_unsafe_raw_sql_deprecated { Post.order(["author_id", "len(title)"]).pluck(:id) }
|
|
1271
|
+
ids_disabled = with_unsafe_raw_sql_disabled { Post.order(["author_id", "len(title)"]).pluck(:id) }
|
|
1084
1272
|
|
|
1085
1273
|
assert_equal ids_expected, ids_depr
|
|
1086
1274
|
assert_equal ids_expected, ids_disabled
|
|
1087
1275
|
end
|
|
1088
|
-
|
|
1089
|
-
coerce_tests! %r{order: logs deprecation warning for unrecognized column}
|
|
1090
|
-
test "order: logs deprecation warning for unrecognized column" do
|
|
1091
|
-
with_unsafe_raw_sql_deprecated do
|
|
1092
|
-
assert_deprecated(/Dangerous query method/) do
|
|
1093
|
-
Post.order("len(title)")
|
|
1094
|
-
end
|
|
1095
|
-
end
|
|
1096
|
-
end
|
|
1097
|
-
|
|
1098
|
-
coerce_tests! %r{pluck: disallows invalid column name}
|
|
1099
|
-
test "pluck: disallows invalid column name" do
|
|
1100
|
-
with_unsafe_raw_sql_disabled do
|
|
1101
|
-
assert_raises(ActiveRecord::UnknownAttributeReference) do
|
|
1102
|
-
Post.pluck("len(title)")
|
|
1103
|
-
end
|
|
1104
|
-
end
|
|
1105
|
-
end
|
|
1106
|
-
|
|
1107
|
-
coerce_tests! %r{pluck: disallows invalid column name amongst valid names}
|
|
1108
|
-
test "pluck: disallows invalid column name amongst valid names" do
|
|
1109
|
-
with_unsafe_raw_sql_disabled do
|
|
1110
|
-
assert_raises(ActiveRecord::UnknownAttributeReference) do
|
|
1111
|
-
Post.pluck(:title, "len(title)")
|
|
1112
|
-
end
|
|
1113
|
-
end
|
|
1114
|
-
end
|
|
1115
|
-
|
|
1116
|
-
coerce_tests! %r{pluck: disallows invalid column names with includes}
|
|
1117
|
-
test "pluck: disallows invalid column names with includes" do
|
|
1118
|
-
with_unsafe_raw_sql_disabled do
|
|
1119
|
-
assert_raises(ActiveRecord::UnknownAttributeReference) do
|
|
1120
|
-
Post.includes(:comments).pluck(:title, "len(title)")
|
|
1121
|
-
end
|
|
1122
|
-
end
|
|
1123
|
-
end
|
|
1124
|
-
|
|
1125
|
-
coerce_tests! %r{pluck: logs deprecation warning}
|
|
1126
|
-
test "pluck: logs deprecation warning" do
|
|
1127
|
-
with_unsafe_raw_sql_deprecated do
|
|
1128
|
-
assert_deprecated(/Dangerous query method/) do
|
|
1129
|
-
Post.includes(:comments).pluck(:title, "len(title)")
|
|
1130
|
-
end
|
|
1131
|
-
end
|
|
1132
|
-
end
|
|
1133
1276
|
end
|
|
1134
1277
|
|
|
1135
|
-
|
|
1136
1278
|
class ReservedWordTest < ActiveRecord::TestCase
|
|
1137
1279
|
coerce_tests! :test_change_columns
|
|
1138
1280
|
def test_change_columns_coerced
|
|
@@ -1143,32 +1285,29 @@ class ReservedWordTest < ActiveRecord::TestCase
|
|
|
1143
1285
|
end
|
|
1144
1286
|
end
|
|
1145
1287
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
1288
|
class OptimisticLockingTest < ActiveRecord::TestCase
|
|
1149
1289
|
# We do not allow updating identities, but we can test using a non-identity key
|
|
1150
1290
|
coerce_tests! :test_update_with_dirty_primary_key
|
|
1151
1291
|
def test_update_with_dirty_primary_key_coerced
|
|
1152
1292
|
assert_raises(ActiveRecord::RecordNotUnique) do
|
|
1153
|
-
record = StringKeyObject.find(
|
|
1154
|
-
record.id =
|
|
1293
|
+
record = StringKeyObject.find("record1")
|
|
1294
|
+
record.id = "record2"
|
|
1155
1295
|
record.save!
|
|
1156
1296
|
end
|
|
1157
1297
|
|
|
1158
|
-
record = StringKeyObject.find(
|
|
1159
|
-
record.id =
|
|
1298
|
+
record = StringKeyObject.find("record1")
|
|
1299
|
+
record.id = "record42"
|
|
1160
1300
|
record.save!
|
|
1161
1301
|
|
|
1162
|
-
assert StringKeyObject.find(
|
|
1302
|
+
assert StringKeyObject.find("record42")
|
|
1163
1303
|
assert_raises(ActiveRecord::RecordNotFound) do
|
|
1164
|
-
StringKeyObject.find(
|
|
1304
|
+
StringKeyObject.find("record1")
|
|
1165
1305
|
end
|
|
1166
1306
|
end
|
|
1167
1307
|
end
|
|
1168
1308
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
1309
|
class RelationMergingTest < ActiveRecord::TestCase
|
|
1310
|
+
# Use nvarchar string (N'') in assert
|
|
1172
1311
|
coerce_tests! :test_merging_with_order_with_binds
|
|
1173
1312
|
def test_merging_with_order_with_binds_coerced
|
|
1174
1313
|
relation = Post.all.merge(Post.order([Arel.sql("title LIKE ?"), "%suffix"]))
|
|
@@ -1176,8 +1315,144 @@ class RelationMergingTest < ActiveRecord::TestCase
|
|
|
1176
1315
|
end
|
|
1177
1316
|
end
|
|
1178
1317
|
|
|
1318
|
+
module ActiveRecord
|
|
1319
|
+
class DatabaseTasksTruncateAllTest < ActiveRecord::TestCase
|
|
1320
|
+
# SQL Server does not allow truncation of tables that are referenced by foreign key
|
|
1321
|
+
# constraints. As this test truncates all tables we would need to remove all foreign
|
|
1322
|
+
# key constraints and then restore them afterwards to get this test to pass.
|
|
1323
|
+
coerce_tests! :test_truncate_tables
|
|
1324
|
+
end
|
|
1325
|
+
end
|
|
1326
|
+
|
|
1327
|
+
require "models/book"
|
|
1328
|
+
class EnumTest < ActiveRecord::TestCase
|
|
1329
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
|
1330
|
+
coerce_tests! %r{enums are distinct per class}
|
|
1331
|
+
test "enums are distinct per class coerced" do
|
|
1332
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
|
1333
|
+
|
|
1334
|
+
send(:'original_enums are distinct per class')
|
|
1335
|
+
ensure
|
|
1336
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
|
1337
|
+
end
|
|
1338
|
+
|
|
1339
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
|
1340
|
+
coerce_tests! %r{creating new objects with enum scopes}
|
|
1341
|
+
test "creating new objects with enum scopes coerced" do
|
|
1342
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
|
1343
|
+
|
|
1344
|
+
send(:'original_creating new objects with enum scopes')
|
|
1345
|
+
ensure
|
|
1346
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
|
1347
|
+
end
|
|
1348
|
+
|
|
1349
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
|
1350
|
+
coerce_tests! %r{enums are inheritable}
|
|
1351
|
+
test "enums are inheritable coerced" do
|
|
1352
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
|
1353
|
+
|
|
1354
|
+
send(:'original_enums are inheritable')
|
|
1355
|
+
ensure
|
|
1356
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
|
1357
|
+
end
|
|
1358
|
+
|
|
1359
|
+
# Need to remove index as SQL Server considers NULLs on a unique-index to be equal unlike PostgreSQL/MySQL/SQLite.
|
|
1360
|
+
coerce_tests! %r{declare multiple enums at a time}
|
|
1361
|
+
test "declare multiple enums at a time coerced" do
|
|
1362
|
+
Book.connection.remove_index(:books, column: [:author_id, :name])
|
|
1363
|
+
|
|
1364
|
+
send(:'original_declare multiple enums at a time')
|
|
1365
|
+
ensure
|
|
1366
|
+
Book.connection.add_index(:books, [:author_id, :name], unique: true)
|
|
1367
|
+
end
|
|
1368
|
+
end
|
|
1369
|
+
|
|
1370
|
+
require "models/task"
|
|
1371
|
+
class QueryCacheExpiryTest < ActiveRecord::TestCase
|
|
1372
|
+
# SQL Server does not support skipping or upserting duplicates.
|
|
1373
|
+
coerce_tests! :test_insert_all
|
|
1374
|
+
def test_insert_all_coerced
|
|
1375
|
+
assert_raises(ArgumentError, /does not support skipping duplicates/) do
|
|
1376
|
+
Task.cache { Task.insert({ starting: Time.now }) }
|
|
1377
|
+
end
|
|
1378
|
+
|
|
1379
|
+
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
|
|
1380
|
+
Task.cache { Task.insert_all!([{ starting: Time.now }]) }
|
|
1381
|
+
end
|
|
1382
|
+
|
|
1383
|
+
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
|
|
1384
|
+
Task.cache { Task.insert!({ starting: Time.now }) }
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
assert_called(ActiveRecord::Base.connection, :clear_query_cache, times: 2) do
|
|
1388
|
+
Task.cache { Task.insert_all!([{ starting: Time.now }]) }
|
|
1389
|
+
end
|
|
1390
|
+
|
|
1391
|
+
assert_raises(ArgumentError, /does not support upsert/) do
|
|
1392
|
+
Task.cache { Task.upsert({ starting: Time.now }) }
|
|
1393
|
+
end
|
|
1394
|
+
|
|
1395
|
+
assert_raises(ArgumentError, /does not support upsert/) do
|
|
1396
|
+
Task.cache { Task.upsert_all([{ starting: Time.now }]) }
|
|
1397
|
+
end
|
|
1398
|
+
end
|
|
1399
|
+
end
|
|
1179
1400
|
|
|
1401
|
+
require "models/citation"
|
|
1180
1402
|
class EagerLoadingTooManyIdsTest < ActiveRecord::TestCase
|
|
1181
|
-
#
|
|
1403
|
+
# Original Rails test fails with SQL Server error message "The query processor ran out of internal resources and
|
|
1404
|
+
# could not produce a query plan". This error goes away if you change database compatibility level to 110 (SQL 2012)
|
|
1405
|
+
# (see https://www.mssqltips.com/sqlservertip/5279/sql-server-error-query-processor-ran-out-of-internal-resources-and-could-not-produce-a-query-plan/).
|
|
1406
|
+
# However, you cannot change the compatibility level during a test. The purpose of the test is to ensure that an
|
|
1407
|
+
# unprepared statement is used if the number of values exceeds the adapter's `bind_params_length`. The coerced test
|
|
1408
|
+
# still does this as there will be 32,768 remaining citation records in the database and the `bind_params_length` of
|
|
1409
|
+
# adapter is 2,098.
|
|
1182
1410
|
coerce_tests! :test_eager_loading_too_may_ids
|
|
1411
|
+
def test_eager_loading_too_may_ids_coerced
|
|
1412
|
+
# Remove excess records.
|
|
1413
|
+
Citation.limit(32768).order(id: :desc).delete_all
|
|
1414
|
+
|
|
1415
|
+
# Perform test
|
|
1416
|
+
citation_count = Citation.count
|
|
1417
|
+
assert_sql(/WHERE \(\[citations\]\.\[id\] IN \(0, 1/) do
|
|
1418
|
+
assert_equal citation_count, Citation.eager_load(:citations).offset(0).size
|
|
1419
|
+
end
|
|
1420
|
+
end
|
|
1421
|
+
end
|
|
1422
|
+
|
|
1423
|
+
class LogSubscriberTest < ActiveRecord::TestCase
|
|
1424
|
+
# Call original test from coerced test. Fixes issue on CI with Rails installed as a gem.
|
|
1425
|
+
coerce_tests! :test_vebose_query_logs
|
|
1426
|
+
def test_vebose_query_logs_coerced
|
|
1427
|
+
original_test_vebose_query_logs
|
|
1428
|
+
end
|
|
1429
|
+
end
|
|
1430
|
+
|
|
1431
|
+
class ActiveRecordSchemaTest < ActiveRecord::TestCase
|
|
1432
|
+
# Workaround for randomly failing test.
|
|
1433
|
+
coerce_tests! :test_has_primary_key
|
|
1434
|
+
def test_has_primary_key_coerced
|
|
1435
|
+
@schema_migration.reset_column_information
|
|
1436
|
+
original_test_has_primary_key
|
|
1437
|
+
end
|
|
1438
|
+
end
|
|
1439
|
+
|
|
1440
|
+
module ActiveRecord
|
|
1441
|
+
module ConnectionAdapters
|
|
1442
|
+
class ReaperTest < ActiveRecord::TestCase
|
|
1443
|
+
# Coerce can be removed if Rails version > 6.0.3
|
|
1444
|
+
coerce_tests! :test_connection_pool_starts_reaper_in_fork unless Process.respond_to?(:fork)
|
|
1445
|
+
end
|
|
1446
|
+
end
|
|
1447
|
+
end
|
|
1448
|
+
|
|
1449
|
+
class FixturesTest < ActiveRecord::TestCase
|
|
1450
|
+
# Skip test on Windows. Skip can be removed when Rails PR https://github.com/rails/rails/pull/39234 has been merged.
|
|
1451
|
+
coerce_tests! :test_binary_in_fixtures if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
|
1452
|
+
end
|
|
1453
|
+
|
|
1454
|
+
class ReloadModelsTest < ActiveRecord::TestCase
|
|
1455
|
+
# Skip test on Windows. The number of arguements passed to `IO.popen` in
|
|
1456
|
+
# `activesupport/lib/active_support/testing/isolation.rb` exceeds what Windows can handle.
|
|
1457
|
+
coerce_tests! :test_has_one_with_reload if RbConfig::CONFIG["host_os"] =~ /mswin|mingw/
|
|
1183
1458
|
end
|