summaryrefslogtreecommitdiff
path: root/spec/support/matchers
diff options
context:
space:
mode:
authorKamil Trzciński <ayufan@ayufan.eu>2019-06-19 11:18:04 +0200
committerKamil Trzciński <ayufan@ayufan.eu>2019-06-19 12:23:05 +0200
commit3f543cd2c93d987723d51d629000b5550eb59636 (patch)
treef39d5b2261ee9b3cddc8ab9ce9d35eb0b4a95fae /spec/support/matchers
parent8b55aaee33403c60fefe53a7e58a398c50019388 (diff)
downloadgitlab-ce-3f543cd2c93d987723d51d629000b5550eb59636.tar.gz
Fix N+1 problem in `JobsController#index`fix-jobs-controller-index-n-1
This adds missing preloads, and introduces additional n+1 matcher to look for duplicates.
Diffstat (limited to 'spec/support/matchers')
-rw-r--r--spec/support/matchers/be_n_plus_1_query.rb62
1 files changed, 62 insertions, 0 deletions
diff --git a/spec/support/matchers/be_n_plus_1_query.rb b/spec/support/matchers/be_n_plus_1_query.rb
new file mode 100644
index 00000000000..bbfd1897f04
--- /dev/null
+++ b/spec/support/matchers/be_n_plus_1_query.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Nplus1QueryHelpers
+ DEFAULT_THRESHOLD = 3
+
+ def with_threshold(threshold)
+ @threshold = threshold
+ self
+ end
+
+ def for_query(query)
+ @query = query
+ self
+ end
+
+ def threshold
+ @threshold || DEFAULT_THRESHOLD
+ end
+
+ def occurrences
+ @occurrences ||=
+ if @query
+ recorder.occurrences.select { |recorded, count| recorded =~ @query }
+ else
+ recorder.occurrences
+ end
+ end
+
+ def over_threshold
+ occurrences.select do |recorded, count|
+ count > threshold
+ end
+ end
+
+ def recorder
+ @recorder ||= ActiveRecord::QueryRecorder.new(&@subject_block)
+ end
+
+ def verify_count(&block)
+ @subject_block = block
+ over_threshold.present?
+ end
+
+ def failure_message
+ log_message = over_threshold.to_yaml
+ "The following queries are executed more than #{threshold} time(s):\n#{log_message}"
+ end
+end
+
+RSpec::Matchers.define :be_n_plus_1_query do
+ supports_block_expectations
+
+ include Nplus1QueryHelpers
+
+ match do |block|
+ verify_count(&block)
+ end
+
+ failure_message_when_negated do |actual|
+ failure_message
+ end
+end