Skip to content

Commit f644f7d

Browse files
committed
Extract methods assert_queries and assert_no_queries
Both methods are defined in multiple parts of the framework. It would be useful to put them in a proper place, so that repetition is avoided. I chose the implementation from `ActiveRecord` because it's a bit more complete with the `SQLCounter` class, and also because other parts depend on it.
1 parent 6d3acaf commit f644f7d

File tree

6 files changed

+59
-86
lines changed

6 files changed

+59
-86
lines changed

actiontext/test/test_helper.rb

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
require "rails/test_unit/reporter"
1111
Rails::TestUnitReporter.executable = "bin/test"
1212

13+
require "active_record/testing/query_assertions"
14+
1315
# Disable available locale checks to allow to add locale after initialized.
1416
I18n.enforce_available_locales = false
1517

@@ -22,22 +24,7 @@
2224
end
2325

2426
class ActiveSupport::TestCase
25-
def assert_queries(expected_count)
26-
ActiveRecord::Base.connection.materialize_transactions
27-
28-
queries = []
29-
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
30-
queries << payload[:sql] unless %w[ SCHEMA TRANSACTION ].include?(payload[:name])
31-
end
32-
33-
yield.tap do
34-
assert_equal expected_count, queries.size, "#{queries.size} instead of #{expected_count} queries were executed. #{queries.inspect}"
35-
end
36-
end
37-
38-
def assert_no_queries(&block)
39-
assert_queries(0, &block)
40-
end
27+
include ActiveRecord::Testing::QueryAssertions
4128

4229
private
4330
def create_file_blob(filename:, content_type:, metadata: nil)

actionview/test/activerecord/relation_cache_test.rb

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# frozen_string_literal: true
22

33
require "active_record_unit"
4+
require "active_record/testing/query_assertions"
45

56
class RelationCacheTest < ActionView::TestCase
7+
include ActiveRecord::Testing::QueryAssertions
8+
69
tests ActionView::Helpers::CacheHelper
710

811
def setup
@@ -24,17 +27,4 @@ def test_cache_relation_other
2427
end
2528

2629
def view_cache_dependencies; []; end
27-
28-
def assert_queries(num)
29-
ActiveRecord::Base.connection.materialize_transactions
30-
count = 0
31-
32-
ActiveSupport::Notifications.subscribe("sql.active_record") do |_name, _start, _finish, _id, payload|
33-
count += 1 unless ["SCHEMA", "TRANSACTION"].include? payload[:name]
34-
end
35-
36-
result = yield
37-
assert_equal num, count, "#{count} instead of #{num} queries were executed."
38-
result
39-
end
4030
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
module ActiveRecord
4+
module Testing
5+
module QueryAssertions # :nodoc:
6+
def assert_queries(expected_count = 1, options = {})
7+
ignore_none = options.fetch(:ignore_none) { expected_count == :any }
8+
ActiveRecord::Base.connection.materialize_transactions
9+
SQLCounter.clear_log
10+
result = yield
11+
the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
12+
13+
if expected_count == :any
14+
assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
15+
else
16+
message = "#{the_log.size} instead of #{expected_count} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
17+
assert_equal expected_count, the_log.size, message
18+
end
19+
20+
result
21+
end
22+
23+
def assert_no_queries(&block)
24+
assert_queries(0, &block)
25+
end
26+
27+
class SQLCounter # :nodoc:
28+
class << self
29+
attr_accessor :ignored_sql, :log, :log_all
30+
def clear_log; self.log = []; self.log_all = []; end
31+
end
32+
33+
clear_log
34+
35+
def call(*, values)
36+
return if values[:cached]
37+
38+
sql = values[:sql]
39+
self.class.log_all << sql
40+
self.class.log << sql unless ["SCHEMA", "TRANSACTION"].include? values[:name]
41+
end
42+
end
43+
44+
ActiveSupport::Notifications.subscribe("sql.active_record", SQLCounter.new)
45+
end
46+
end
47+
end

activerecord/test/cases/dirty_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ def test_datetime_attribute_doesnt_change_if_zone_is_modified_in_string
649649
jon = Person.create! first_name: "Jon"
650650
end
651651

652-
assert ActiveRecord::SQLCounter.log_all.none? { |sql| sql.include?("followers_count") }
652+
assert SQLCounter.log_all.none? { |sql| sql.include?("followers_count") }
653653

654654
jon.reload
655655
assert_equal "Jon", jon.first_name

activerecord/test/cases/test_case.rb

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require "active_support/testing/autorun"
55
require "active_support/testing/method_call_assertions"
66
require "active_support/testing/stream"
7+
require "active_record/testing/query_assertions"
78
require "active_record/fixtures"
89

910
require "cases/validations_repair_helper"
@@ -14,6 +15,7 @@ module ActiveRecord
1415
# Defines some test assertions to test against SQL queries.
1516
class TestCase < ActiveSupport::TestCase #:nodoc:
1617
include ActiveSupport::Testing::MethodCallAssertions
18+
include ActiveRecord::Testing::QueryAssertions
1719
include ActiveSupport::Testing::Stream
1820
include ActiveRecord::TestFixtures
1921
include ActiveRecord::ValidationsRepairHelper
@@ -47,26 +49,6 @@ def assert_sql(*patterns_to_match)
4749
assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map(&:inspect).join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}"
4850
end
4951

50-
def assert_queries(num = 1, options = {})
51-
ignore_none = options.fetch(:ignore_none) { num == :any }
52-
ActiveRecord::Base.connection.materialize_transactions
53-
SQLCounter.clear_log
54-
x = yield
55-
the_log = ignore_none ? SQLCounter.log_all : SQLCounter.log
56-
if num == :any
57-
assert_operator the_log.size, :>=, 1, "1 or more queries expected, but none were executed."
58-
else
59-
mesg = "#{the_log.size} instead of #{num} queries were executed.#{the_log.size == 0 ? '' : "\nQueries:\n#{the_log.join("\n")}"}"
60-
assert_equal num, the_log.size, mesg
61-
end
62-
x
63-
end
64-
65-
def assert_no_queries(options = {}, &block)
66-
options.reverse_merge! ignore_none: true
67-
assert_queries(0, options, &block)
68-
end
69-
7052
def assert_column(model, column_name, msg = nil)
7153
assert has_column?(model, column_name), msg
7254
end
@@ -135,23 +117,4 @@ def self.run(*args)
135117
super if current_adapter?(:SQLite3Adapter)
136118
end
137119
end
138-
139-
class SQLCounter
140-
class << self
141-
attr_accessor :ignored_sql, :log, :log_all
142-
def clear_log; self.log = []; self.log_all = []; end
143-
end
144-
145-
clear_log
146-
147-
def call(name, start, finish, message_id, values)
148-
return if values[:cached]
149-
150-
sql = values[:sql]
151-
self.class.log_all << sql
152-
self.class.log << sql unless ["SCHEMA", "TRANSACTION"].include? values[:name]
153-
end
154-
end
155-
156-
ActiveSupport::Notifications.subscribe("sql.active_record", SQLCounter.new)
157120
end

activestorage/test/test_helper.rb

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
require "active_support/core_ext/object/try"
1010
require "active_support/testing/autorun"
1111
require "active_support/configuration_file"
12+
require "active_record/testing/query_assertions"
1213
require "active_storage/service/mirror_service"
1314
require "image_processing/mini_magick"
1415

@@ -46,6 +47,8 @@
4647
ActiveStorage::FixtureSet.file_fixture_path = File.expand_path("fixtures/files", __dir__)
4748

4849
class ActiveSupport::TestCase
50+
include ActiveRecord::Testing::QueryAssertions
51+
4952
self.file_fixture_path = ActiveStorage::FixtureSet.file_fixture_path
5053

5154
include ActiveRecord::TestFixtures
@@ -60,23 +63,6 @@ class ActiveSupport::TestCase
6063
ActiveStorage::Current.reset
6164
end
6265

63-
def assert_queries(expected_count)
64-
ActiveRecord::Base.connection.materialize_transactions
65-
66-
queries = []
67-
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
68-
queries << payload[:sql] unless %w[ SCHEMA TRANSACTION ].include?(payload[:name])
69-
end
70-
71-
yield.tap do
72-
assert_equal expected_count, queries.size, "#{queries.size} instead of #{expected_count} queries were executed. #{queries.inspect}"
73-
end
74-
end
75-
76-
def assert_no_queries(&block)
77-
assert_queries(0, &block)
78-
end
79-
8066
private
8167
def create_blob(key: nil, data: "Hello world!", filename: "hello.txt", content_type: "text/plain", identify: true, service_name: nil, record: nil)
8268
ActiveStorage::Blob.create_and_upload! key: key, io: StringIO.new(data), filename: filename, content_type: content_type, identify: identify, service_name: service_name, record: record

0 commit comments

Comments
 (0)