# frozen_string_literal: truemoduleActiveRecordmoduleAssertionsmoduleQueryAssertions# Asserts that the number of SQL queries executed in the given block matches the expected count.## # Check for exact number of queries# assert_queries_count(1) { Post.first }## # Check for any number of queries# assert_queries_count { Post.first }## If the +:include_schema+ option is provided, any queries (including schema related) are counted.## assert_queries_count(1, include_schema: true) { Post.columns }#defassert_queries_count(count=nil,include_schema: false,&block)ActiveRecord::Base.lease_connection.materialize_transactionscounter=SQLCounter.newActiveSupport::Notifications.subscribed(counter,"sql.active_record")doresult=_assert_nothing_raised_or_warn("assert_queries_count",&block)queries=include_schema?counter.log_all:counter.logifcountassert_equalcount,queries.size,"#{queries.size} instead of #{count} queries were executed. Queries: #{queries.join("\n\n")}"elseassert_operatorqueries.size,:>=,1,"1 or more queries expected, but none were executed.#{queries.empty??'':"\nQueries:\n#{queries.join("\n")}"}"endresultendend# Asserts that no SQL queries are executed in the given block.## assert_no_queries { post.comments }## If the +:include_schema+ option is provided, any queries (including schema related) are counted.## assert_no_queries(include_schema: true) { Post.columns }#defassert_no_queries(include_schema: false,&block)assert_queries_count(0,include_schema: include_schema,&block)end# Asserts that the SQL queries executed in the given block match expected pattern.## # Check for exact number of queries# assert_queries_match(/LIMIT \?/, count: 1) { Post.first }## # Check for any number of queries# assert_queries_match(/LIMIT \?/) { Post.first }## If the +:include_schema+ option is provided, any queries (including schema related)# that match the matcher are considered.## assert_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }#defassert_queries_match(match,count: nil,include_schema: false,&block)ActiveRecord::Base.lease_connection.materialize_transactionscounter=SQLCounter.newActiveSupport::Notifications.subscribed(counter,"sql.active_record")doresult=_assert_nothing_raised_or_warn("assert_queries_match",&block)queries=include_schema?counter.log_all:counter.logmatched_queries=queries.select{|query|match===query}ifcountassert_equalcount,matched_queries.size,"#{matched_queries.size} instead of #{count} queries were executed.#{queries.empty??'':"\nQueries:\n#{queries.join("\n")}"}"elseassert_operatormatched_queries.size,:>=,1,"1 or more queries expected, but none were executed.#{queries.empty??'':"\nQueries:\n#{queries.join("\n")}"}"endresultendend# Asserts that no SQL queries matching the pattern are executed in the given block.## assert_no_queries_match(/SELECT/i) { post.comments }## If the +:include_schema+ option is provided, any queries (including schema related)# that match the matcher are counted.## assert_no_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }#defassert_no_queries_match(match,include_schema: false,&block)assert_queries_match(match,count: 0,include_schema: include_schema,&block)endclassSQLCounter# :nodoc:attr_reader:log_full,:log_alldefinitialize@log_full=[]@log_all=[]enddeflog@log_full.map(&:first)enddefcall(*,payload)returnifpayload[:cached]sql=payload[:sql]@log_all<<sqlunlesspayload[:name]=="SCHEMA"bound_values=(payload[:binds]||[]).mapdo|value|value=value.value_for_databaseifvalue.respond_to?(:value_for_database)valueend@log_full<<[sql,bound_values]endendendendendend