Skip to content

Commit 95b0c8e

Browse files
authored
When asserting queries performed, insert placeholder query for release save-point (#1168)
1 parent 9849019 commit 95b0c8e

File tree

4 files changed

+39
-34
lines changed

4 files changed

+39
-34
lines changed

lib/active_record/connection_adapters/sqlserver/savepoints.rb

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ def exec_rollback_to_savepoint(name = current_savepoint_name)
1616
internal_execute("ROLLBACK TRANSACTION #{name}", "TRANSACTION")
1717
end
1818

19+
# SQL Server does require save-points to be explicitly released.
20+
# See https://stackoverflow.com/questions/3101312/sql-server-2008-no-release-savepoint-for-current-transaction
1921
def release_savepoint(_name)
2022
end
2123
end

test/cases/coerced_tests.rb

+5-33
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,6 @@ def test_update_date_time_attributes_with_default_timezone_local
243243
end
244244
end
245245

246-
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
247-
# SQL Server does not have query for release_savepoint
248-
coerce_tests! :test_associate_existing
249-
def test_associate_existing_coerced
250-
post = posts(:thinking)
251-
person = people(:david)
252-
253-
assert_queries_count(2) do
254-
post.people << person
255-
end
256-
257-
assert_queries_count(1) do
258-
assert_includes post.people, person
259-
end
260-
261-
assert_includes post.reload.people.reload, person
262-
end
263-
end
264-
265246
class BelongsToAssociationsTest < ActiveRecord::TestCase
266247
# Since @client.firm is a single first/top, and we use FETCH the order clause is used.
267248
coerce_tests! :test_belongs_to_does_not_use_order_by
@@ -1335,18 +1316,6 @@ def test_registering_new_handlers_for_association_coerced
13351316
end
13361317
end
13371318

1338-
class PrimaryKeysTest < ActiveRecord::TestCase
1339-
# SQL Server does not have query for release_savepoint
1340-
coerce_tests! :test_create_without_primary_key_no_extra_query
1341-
def test_create_without_primary_key_no_extra_query_coerced
1342-
klass = Class.new(ActiveRecord::Base) do
1343-
self.table_name = "dashboards"
1344-
end
1345-
klass.create! # warmup schema cache
1346-
assert_queries_count(2, include_schema: true) { klass.create! }
1347-
end
1348-
end
1349-
13501319
require "models/task"
13511320
class QueryCacheTest < ActiveRecord::TestCase
13521321
# SQL Server adapter not in list of supported adapters in original test.
@@ -1633,8 +1602,11 @@ def test_releasing_named_savepoints_coerced
16331602

16341603
Topic.lease_connection.create_savepoint("another")
16351604
Topic.lease_connection.release_savepoint("another")
1636-
# We do not have a notion of releasing, so this does nothing vs raise an error.
1637-
Topic.lease_connection.release_savepoint("another")
1605+
1606+
# We do not have a notion of releasing, so this does nothing and doesn't raise an error.
1607+
assert_nothing_raised do
1608+
Topic.lease_connection.release_savepoint("another")
1609+
end
16381610
end
16391611
end
16401612

test/cases/helper_sqlserver.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
require "support/load_schema_sqlserver"
1212
require "support/coerceable_test_sqlserver"
1313
require "support/connection_reflection"
14+
require "support/query_assertions"
1415
require "mocha/minitest"
1516

1617
module ActiveRecord
@@ -19,7 +20,8 @@ class TestCase < ActiveSupport::TestCase
1920

2021
include ARTest::SQLServer::CoerceableTest,
2122
ARTest::SQLServer::ConnectionReflection,
22-
ActiveSupport::Testing::Stream
23+
ActiveSupport::Testing::Stream,
24+
ARTest::SQLServer::QueryAssertions
2325

2426
let(:logger) { ActiveRecord::Base.logger }
2527

test/support/query_assertions.rb

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module ARTest
2+
module SQLServer
3+
module QueryAssertions
4+
def assert_queries_count(count = nil, include_schema: false, &block)
5+
ActiveRecord::Base.lease_connection.materialize_transactions
6+
7+
counter = ActiveRecord::Assertions::QueryAssertions::SQLCounter.new
8+
ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
9+
result = _assert_nothing_raised_or_warn("assert_queries_count", &block)
10+
queries = include_schema ? counter.log_all : counter.log
11+
12+
# Start of monkey-patch
13+
# Rails tests expect a save-point to be released at the end of the test. SQL Server does not release
14+
# save-points and so the number of queries will be off by one. This monkey patch adds a placeholder query
15+
# to the end of the queries array to account for the missing save-point release.
16+
queries.append "/* release savepoint placeholder for testing */" if queries.first =~ /SAVE TRANSACTION \S+/
17+
# End of monkey-patch
18+
19+
if count
20+
assert_equal count, queries.size, "#{queries.size} instead of #{count} queries were executed. Queries: #{queries.join("\n\n")}"
21+
else
22+
assert_operator queries.size, :>=, 1, "1 or more queries expected, but none were executed.#{queries.empty? ? '' : "\nQueries:\n#{queries.join("\n")}"}"
23+
end
24+
result
25+
end
26+
end
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)