query_owl 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2654c621778910c1a0b1926398480e21b967f86c63ff45b642e635d80bfebcd0
4
- data.tar.gz: 54245db5c8aa3a64869f3ce18b9c95b662d01ba58a042150ea551f19e1bf7299
3
+ metadata.gz: 9d6d1c90011594e84ad366b86242261eb507c646bbbd99567ee68e764f79fed3
4
+ data.tar.gz: 6b3d04a4eeba7e6cd61f77ac1c86d9267490cb68bc4bee375bf3fca39db21c48
5
5
  SHA512:
6
- metadata.gz: 5d1a2a46359810b4f5e482097264c6d1d402c4344f5cf29b672d89a9c834c04e81936f07f3111454abf549e12c5a30614e6829c5d62563860de6b625220ce234
7
- data.tar.gz: 41561e881c73aac6ed2ce8b7d3fc4f1a9f83d35fe92f4473713d274978451d9d7cd4ae7fada1af25739d3222457216ae13fdfb015b41bc8cf87116ee8aaa9b1a
6
+ metadata.gz: 48dd728246c8226b5fc04bf819e85712e8eaf5453d1fe77ca1ce3ba012f7399a52af50cffacb652c5958f2ab086c35270930fed9c093971b3e446bc3846f1756
7
+ data.tar.gz: 1f26cb6d3c28dccf5708446b4c9e17ce2f334af66ae8b0ed6c6d92eb36440818b4c1feff3cf4ef124f455e54e050641eadc8952aa0a8d59c5b2a4ed50672a8cf
@@ -41,6 +41,19 @@ QueryOwl.configure do |config|
41
41
  # Controllers to skip — matched against the Rails controller name (e.g. "rails/health").
42
42
  # config.ignore_controllers = ["rails/health", "admin/metrics"]
43
43
 
44
+ # Test helper — opt-in RSpec matchers and Minitest assertions.
45
+ # Add to spec/rails_helper.rb (or test/test_helper.rb for Minitest):
46
+ #
47
+ # require "query_owl/test_helper"
48
+ # RSpec.configure { |c| c.include QueryOwl::TestHelper }
49
+ # # or: class ActiveSupport::TestCase; include QueryOwl::TestHelper; end
50
+ #
51
+ # Then use: expect { }.not_to trigger_n_plus_one
52
+ # expect { }.not_to trigger_slow_query
53
+ # expect { }.not_to trigger_unused_eager_load
54
+ # assert_no_n_plus_one { }
55
+ # assert_no_slow_query { }
56
+
44
57
  # Notifiers receive each detected event via #call(event).
45
58
  # Defaults to [QueryOwl::Notifiers::Logger] which writes to Rails.logger.
46
59
  # Use Console for TTY-aware colorized output (yellow: N+1, red: slow query).
@@ -0,0 +1,85 @@
1
+ require "query_owl"
2
+
3
+ module QueryOwl
4
+ module TestHelper
5
+ # Runs block with QueryOwl's trackers active and returns detected events.
6
+ # Isolated from config.enabled and config.raise_on_n_plus_one.
7
+ def self.capture_events
8
+ QueryTracker.start!
9
+ EagerLoadTracker.start!
10
+ yield
11
+ queries = QueryTracker.stop!
12
+ eager_data = EagerLoadTracker.stop!
13
+ Detector.detect_n_plus_one(queries) +
14
+ Detector.detect_slow_queries(queries) +
15
+ Detector.detect_unused_eager_loads(eager_data)
16
+ rescue
17
+ QueryTracker.stop!
18
+ EagerLoadTracker.stop!
19
+ raise
20
+ end
21
+
22
+ # RSpec block matchers — use with expect { }.to / not_to
23
+
24
+ def trigger_n_plus_one
25
+ EventTypeMatcher.new(:n_plus_one)
26
+ end
27
+
28
+ def trigger_slow_query
29
+ EventTypeMatcher.new(:slow_query)
30
+ end
31
+
32
+ def trigger_unused_eager_load
33
+ EventTypeMatcher.new(:unused_eager_load)
34
+ end
35
+
36
+ # Minitest assertions — call assert_no_n_plus_one { } inside a test method
37
+
38
+ def assert_no_n_plus_one(msg = nil, &block)
39
+ events = QueryOwl::TestHelper.capture_events(&block)
40
+ count = events.count { |e| e[:type] == :n_plus_one }
41
+ assert count.zero?, msg || "Expected no N+1 queries, but #{count} detected"
42
+ end
43
+
44
+ def assert_no_slow_query(msg = nil, &block)
45
+ events = QueryOwl::TestHelper.capture_events(&block)
46
+ count = events.count { |e| e[:type] == :slow_query }
47
+ assert count.zero?, msg || "Expected no slow queries, but #{count} detected"
48
+ end
49
+
50
+ class EventTypeMatcher
51
+ def initialize(type)
52
+ @type = type
53
+ @events = []
54
+ end
55
+
56
+ def matches?(block)
57
+ @events = QueryOwl::TestHelper.capture_events(&block)
58
+ @events.any? { |e| e[:type] == @type }
59
+ end
60
+
61
+ def does_not_match?(block)
62
+ !matches?(block)
63
+ end
64
+
65
+ def supports_block_expectations?
66
+ true
67
+ end
68
+
69
+ def failure_message
70
+ "expected block to trigger #{label} but none were detected"
71
+ end
72
+
73
+ def failure_message_when_negated
74
+ n = @events.count { |e| e[:type] == @type }
75
+ "expected block not to trigger #{label} but #{n} detected"
76
+ end
77
+
78
+ private
79
+
80
+ def label
81
+ @type.to_s.tr("_", " ")
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,3 +1,3 @@
1
1
  module QueryOwl
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: query_owl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith
@@ -63,6 +63,7 @@ files:
63
63
  - lib/query_owl/notifiers/stdout.rb
64
64
  - lib/query_owl/query_tracker.rb
65
65
  - lib/query_owl/request_context.rb
66
+ - lib/query_owl/test_helper.rb
66
67
  - lib/query_owl/version.rb
67
68
  - lib/tasks/query_owl_tasks.rake
68
69
  homepage: https://github.com/eclectic-coding/query_owl