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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d6d1c90011594e84ad366b86242261eb507c646bbbd99567ee68e764f79fed3
|
|
4
|
+
data.tar.gz: 6b3d04a4eeba7e6cd61f77ac1c86d9267490cb68bc4bee375bf3fca39db21c48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
data/lib/query_owl/version.rb
CHANGED
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.
|
|
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
|