bullet 5.8.1 → 6.1.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 +5 -5
- data/.travis.yml +22 -1
- data/CHANGELOG.md +24 -1
- data/Gemfile.mongoid-7.0 +15 -0
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/Gemfile.rails-4.2 +1 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +1 -1
- data/Gemfile.rails-5.2 +1 -1
- data/Gemfile.rails-6.0 +15 -0
- data/README.md +24 -10
- data/lib/bullet.rb +42 -17
- data/lib/bullet/active_job.rb +9 -0
- data/lib/bullet/active_record4.rb +9 -32
- data/lib/bullet/active_record41.rb +7 -27
- data/lib/bullet/active_record42.rb +8 -24
- data/lib/bullet/active_record5.rb +188 -179
- data/lib/bullet/active_record52.rb +176 -168
- data/lib/bullet/active_record60.rb +267 -0
- data/lib/bullet/bullet_xhr.js +63 -0
- data/lib/bullet/dependency.rb +48 -34
- data/lib/bullet/detector/association.rb +26 -20
- data/lib/bullet/detector/base.rb +1 -2
- data/lib/bullet/detector/counter_cache.rb +13 -9
- data/lib/bullet/detector/n_plus_one_query.rb +22 -12
- data/lib/bullet/detector/unused_eager_loading.rb +6 -3
- data/lib/bullet/ext/object.rb +4 -2
- data/lib/bullet/mongoid4x.rb +2 -6
- data/lib/bullet/mongoid5x.rb +2 -6
- data/lib/bullet/mongoid6x.rb +2 -6
- data/lib/bullet/mongoid7x.rb +57 -0
- data/lib/bullet/notification/base.rb +14 -18
- data/lib/bullet/notification/n_plus_one_query.rb +2 -4
- data/lib/bullet/notification/unused_eager_loading.rb +2 -4
- data/lib/bullet/rack.rb +39 -20
- data/lib/bullet/stack_trace_filter.rb +6 -12
- data/lib/bullet/version.rb +1 -1
- data/lib/generators/bullet/install_generator.rb +4 -2
- data/perf/benchmark.rb +8 -14
- data/spec/bullet/detector/counter_cache_spec.rb +5 -5
- data/spec/bullet/detector/n_plus_one_query_spec.rb +7 -3
- data/spec/bullet/detector/unused_eager_loading_spec.rb +29 -12
- data/spec/bullet/ext/object_spec.rb +9 -4
- data/spec/bullet/notification/base_spec.rb +1 -3
- data/spec/bullet/notification/n_plus_one_query_spec.rb +18 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
- data/spec/bullet/rack_spec.rb +30 -6
- data/spec/bullet/registry/association_spec.rb +2 -2
- data/spec/bullet/registry/base_spec.rb +1 -1
- data/spec/bullet_spec.rb +10 -29
- data/spec/integration/active_record/association_spec.rb +45 -136
- data/spec/integration/counter_cache_spec.rb +11 -31
- data/spec/integration/mongoid/association_spec.rb +18 -32
- data/spec/models/folder.rb +1 -2
- data/spec/models/group.rb +1 -2
- data/spec/models/page.rb +1 -2
- data/spec/models/writer.rb +1 -2
- data/spec/spec_helper.rb +6 -10
- data/spec/support/bullet_ext.rb +8 -9
- data/spec/support/mongo_seed.rb +2 -16
- data/test.sh +2 -0
- data/update.sh +1 -0
- metadata +9 -4
@@ -13,39 +13,45 @@ module Bullet
|
|
13
13
|
|
14
14
|
context '.call_associations' do
|
15
15
|
it 'should get empty array if eager_loadings' do
|
16
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([
|
16
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(%i[association]))).to be_empty
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should get call associations if object and association are both in eager_loadings and call_object_associations' do
|
20
20
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
21
21
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
22
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([
|
22
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(%i[association]))).to eq(
|
23
|
+
%i[association]
|
24
|
+
)
|
23
25
|
end
|
24
26
|
|
25
27
|
it 'should not get call associations if not exist in call_object_associations' do
|
26
28
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
27
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([
|
29
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(%i[association]))).to be_empty
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
31
33
|
context '.diff_object_associations' do
|
32
34
|
it 'should return associations not exist in call_association' do
|
33
|
-
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([
|
35
|
+
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(%i[association]))).to eq(
|
36
|
+
%i[association]
|
37
|
+
)
|
34
38
|
end
|
35
39
|
|
36
40
|
it 'should return empty if associations exist in call_association' do
|
37
41
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
38
42
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
39
|
-
expect(
|
43
|
+
expect(
|
44
|
+
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(%i[association]))
|
45
|
+
).to be_empty
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
43
49
|
context '.check_unused_preload_associations' do
|
44
|
-
let(:paths) { [
|
50
|
+
let(:paths) { %w[/dir1 /dir1/subdir] }
|
45
51
|
it 'should create notification if object_association_diff is not empty' do
|
46
52
|
UnusedEagerLoading.add_object_associations(@post, :association)
|
47
53
|
allow(UnusedEagerLoading).to receive(:caller_in_project).and_return(paths)
|
48
|
-
expect(UnusedEagerLoading).to receive(:create_notification).with(paths, 'Post', [
|
54
|
+
expect(UnusedEagerLoading).to receive(:create_notification).with(paths, 'Post', %i[association])
|
49
55
|
UnusedEagerLoading.check_unused_preload_associations
|
50
56
|
end
|
51
57
|
|
@@ -53,8 +59,10 @@ module Bullet
|
|
53
59
|
UnusedEagerLoading.add_object_associations(@post, :association)
|
54
60
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
55
61
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
56
|
-
expect(
|
57
|
-
|
62
|
+
expect(
|
63
|
+
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(%i[association]))
|
64
|
+
).to be_empty
|
65
|
+
expect(UnusedEagerLoading).not_to receive(:create_notification).with('Post', %i[association])
|
58
66
|
UnusedEagerLoading.check_unused_preload_associations
|
59
67
|
end
|
60
68
|
end
|
@@ -62,14 +70,23 @@ module Bullet
|
|
62
70
|
context '.add_eager_loadings' do
|
63
71
|
it 'should add objects, associations pair when eager_loadings are empty' do
|
64
72
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :associations)
|
65
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
|
73
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
|
74
|
+
[@post.bullet_key, @post2.bullet_key],
|
75
|
+
:associations
|
76
|
+
)
|
66
77
|
end
|
67
78
|
|
68
79
|
it 'should add objects, associations pair for existing eager_loadings' do
|
69
80
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
|
70
81
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
|
71
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
|
72
|
-
|
82
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
|
83
|
+
[@post.bullet_key, @post2.bullet_key],
|
84
|
+
:association1
|
85
|
+
)
|
86
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
|
87
|
+
[@post.bullet_key, @post2.bullet_key],
|
88
|
+
:association2
|
89
|
+
)
|
73
90
|
end
|
74
91
|
|
75
92
|
it 'should merge objects, associations pair for existing eager_loadings' do
|
@@ -17,23 +17,28 @@ describe Object do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
context '
|
20
|
+
context 'bullet_primary_key_value' do
|
21
21
|
it 'should return id' do
|
22
22
|
post = Post.first
|
23
|
-
expect(post.
|
23
|
+
expect(post.bullet_primary_key_value).to eq(post.id)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should return primary key value' do
|
27
27
|
post = Post.first
|
28
28
|
Post.primary_key = 'name'
|
29
|
-
expect(post.
|
29
|
+
expect(post.bullet_primary_key_value).to eq(post.name)
|
30
30
|
Post.primary_key = 'id'
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'should return value for multiple primary keys' do
|
34
34
|
post = Post.first
|
35
35
|
allow(Post).to receive(:primary_keys).and_return(%i[category_id writer_id])
|
36
|
-
expect(post.
|
36
|
+
expect(post.bullet_primary_key_value).to eq("#{post.category_id},#{post.writer_id}")
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'it should return nil for unpersisted records' do
|
40
|
+
post = Post.new(id: 123)
|
41
|
+
expect(post.bullet_primary_key_value).to be_nil
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -26,9 +26,7 @@ module Bullet
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should leverage ENV parameter' do
|
29
|
-
temp_env_variable('USER', 'bogus')
|
30
|
-
expect(subject.whoami).to eq('user: bogus')
|
31
|
-
end
|
29
|
+
temp_env_variable('USER', 'bogus') { expect(subject.whoami).to eq('user: bogus') }
|
32
30
|
end
|
33
31
|
|
34
32
|
it 'should return blank if no user available' do
|
@@ -7,9 +7,24 @@ module Bullet
|
|
7
7
|
describe NPlusOneQuery do
|
8
8
|
subject { NPlusOneQuery.new([%w[caller1 caller2]], Post, %i[comments votes], 'path') }
|
9
9
|
|
10
|
-
it
|
11
|
-
|
12
|
-
|
10
|
+
it do
|
11
|
+
expect(subject.body_with_caller).to eq(
|
12
|
+
" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n"
|
13
|
+
)
|
14
|
+
end
|
15
|
+
it do
|
16
|
+
expect([subject.body_with_caller, subject.body_with_caller]).to eq(
|
17
|
+
[
|
18
|
+
" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n",
|
19
|
+
" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n"
|
20
|
+
]
|
21
|
+
)
|
22
|
+
end
|
23
|
+
it do
|
24
|
+
expect(subject.body).to eq(
|
25
|
+
" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])"
|
26
|
+
)
|
27
|
+
end
|
13
28
|
it { expect(subject.title).to eq('USE eager loading in path') }
|
14
29
|
end
|
15
30
|
end
|
@@ -7,7 +7,11 @@ module Bullet
|
|
7
7
|
describe UnusedEagerLoading do
|
8
8
|
subject { UnusedEagerLoading.new([''], Post, %i[comments votes], 'path') }
|
9
9
|
|
10
|
-
it
|
10
|
+
it do
|
11
|
+
expect(subject.body).to eq(
|
12
|
+
" Post => [:comments, :votes]\n Remove from your query: .includes([:comments, :votes])"
|
13
|
+
)
|
14
|
+
end
|
11
15
|
it { expect(subject.title).to eq('AVOID eager loading in path') }
|
12
16
|
end
|
13
17
|
end
|
data/spec/bullet/rack_spec.rb
CHANGED
@@ -45,9 +45,9 @@ module Bullet
|
|
45
45
|
expect(middleware).not_to be_empty(response)
|
46
46
|
end
|
47
47
|
|
48
|
-
it 'should be
|
48
|
+
it 'should be false if response is not found' do
|
49
49
|
response = ['Not Found']
|
50
|
-
expect(middleware).
|
50
|
+
expect(middleware).not_to be_empty(response)
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should be true if response body is empty' do
|
@@ -67,11 +67,13 @@ module Bullet
|
|
67
67
|
|
68
68
|
it 'should change response body if notification is active' do
|
69
69
|
expect(Bullet).to receive(:notification?).and_return(true)
|
70
|
+
allow(Bullet).to receive(:skip_html_injection?).and_return(false)
|
70
71
|
expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
|
72
|
+
expect(middleware).to receive(:xhr_script).and_return('')
|
71
73
|
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
72
|
-
|
74
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
73
75
|
expect(headers['Content-Length']).to eq('56')
|
74
|
-
expect(response).to eq([
|
76
|
+
expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
|
75
77
|
end
|
76
78
|
|
77
79
|
it 'should set the right Content-Length if response body contains accents' do
|
@@ -80,8 +82,22 @@ module Bullet
|
|
80
82
|
app.response = response
|
81
83
|
expect(Bullet).to receive(:notification?).and_return(true)
|
82
84
|
expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
|
83
|
-
|
84
|
-
expect(headers['Content-Length']).to eq(
|
85
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
86
|
+
expect(headers['Content-Length']).to eq((58 + middleware.send(:xhr_script).length).to_s)
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when skip_html_injection is enabled' do
|
90
|
+
it 'should not try to inject html' do
|
91
|
+
expected_response = Support::ResponseDouble.new 'Actual body'
|
92
|
+
app.response = expected_response
|
93
|
+
allow(Bullet).to receive(:notification?).and_return(true)
|
94
|
+
allow(Bullet).to receive(:skip_html_injection?).and_return(true)
|
95
|
+
expect(Bullet).to receive(:gather_inline_notifications).never
|
96
|
+
expect(middleware).to receive(:xhr_script).never
|
97
|
+
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
98
|
+
_, _, response = middleware.call('Content-Type' => 'text/html')
|
99
|
+
expect(response).to eq(expected_response)
|
100
|
+
end
|
85
101
|
end
|
86
102
|
end
|
87
103
|
|
@@ -95,6 +111,14 @@ module Bullet
|
|
95
111
|
end
|
96
112
|
end
|
97
113
|
|
114
|
+
context '#set_header' do
|
115
|
+
it 'should truncate headers to under 8kb' do
|
116
|
+
long_header = ['a' * 1_024] * 10
|
117
|
+
expected_res = (['a' * 1_024] * 7).to_json
|
118
|
+
expect(middleware.set_header({}, 'Dummy-Header', long_header)).to eq(expected_res)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
98
122
|
describe '#response_body' do
|
99
123
|
let(:response) { double }
|
100
124
|
let(:body_string) { '<html><body>My Body</body></html>' }
|
@@ -16,11 +16,11 @@ module Bullet
|
|
16
16
|
|
17
17
|
context '#similarly_associated' do
|
18
18
|
it 'should return similarly associated keys' do
|
19
|
-
expect(subject.similarly_associated('key1', Set.new([
|
19
|
+
expect(subject.similarly_associated('key1', Set.new(%w[value]))).to eq(%w[key1 key2])
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should return empty if key does not exist' do
|
23
|
-
expect(subject.similarly_associated('key3', Set.new([
|
23
|
+
expect(subject.similarly_associated('key3', Set.new(%w[value]))).to be_empty
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/spec/bullet_spec.rb
CHANGED
@@ -17,9 +17,7 @@ describe Bullet, focused: true do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'disable Bullet' do
|
20
|
-
before
|
21
|
-
Bullet.enable = false
|
22
|
-
end
|
20
|
+
before { Bullet.enable = false }
|
23
21
|
|
24
22
|
it 'should be disabled' do
|
25
23
|
expect(subject).to_not be_enable
|
@@ -27,8 +25,8 @@ describe Bullet, focused: true do
|
|
27
25
|
|
28
26
|
context 'enable Bullet again without patching again the orms' do
|
29
27
|
before do
|
30
|
-
expect(Bullet::Mongoid).not_to receive(:enable) if defined?
|
31
|
-
expect(Bullet::ActiveRecord).not_to receive(:enable) if defined?
|
28
|
+
expect(Bullet::Mongoid).not_to receive(:enable) if defined?(Bullet::Mongoid)
|
29
|
+
expect(Bullet::ActiveRecord).not_to receive(:enable) if defined?(Bullet::ActiveRecord)
|
32
30
|
Bullet.enable = true
|
33
31
|
end
|
34
32
|
|
@@ -42,9 +40,7 @@ describe Bullet, focused: true do
|
|
42
40
|
|
43
41
|
describe '#start?' do
|
44
42
|
context 'when bullet is disabled' do
|
45
|
-
before(:each)
|
46
|
-
Bullet.enable = false
|
47
|
-
end
|
43
|
+
before(:each) { Bullet.enable = false }
|
48
44
|
|
49
45
|
it 'should not be started' do
|
50
46
|
expect(Bullet).not_to be_start
|
@@ -53,28 +49,19 @@ describe Bullet, focused: true do
|
|
53
49
|
end
|
54
50
|
|
55
51
|
describe '#debug' do
|
56
|
-
before(:each)
|
57
|
-
$stdout = StringIO.new
|
58
|
-
end
|
52
|
+
before(:each) { $stdout = StringIO.new }
|
59
53
|
|
60
|
-
after(:each)
|
61
|
-
$stdout = STDOUT
|
62
|
-
end
|
54
|
+
after(:each) { $stdout = STDOUT }
|
63
55
|
|
64
56
|
context 'when debug is enabled' do
|
65
|
-
before(:each)
|
66
|
-
ENV['BULLET_DEBUG'] = 'true'
|
67
|
-
end
|
57
|
+
before(:each) { ENV['BULLET_DEBUG'] = 'true' }
|
68
58
|
|
69
|
-
after(:each)
|
70
|
-
ENV['BULLET_DEBUG'] = 'false'
|
71
|
-
end
|
59
|
+
after(:each) { ENV['BULLET_DEBUG'] = 'false' }
|
72
60
|
|
73
61
|
it 'should output debug information' do
|
74
62
|
Bullet.debug('debug_message', 'this is helpful information')
|
75
63
|
|
76
|
-
expect($stdout.string)
|
77
|
-
.to eq("[Bullet][debug_message] this is helpful information\n")
|
64
|
+
expect($stdout.string).to eq("[Bullet][debug_message] this is helpful information\n")
|
78
65
|
end
|
79
66
|
end
|
80
67
|
|
@@ -125,13 +112,7 @@ describe Bullet, focused: true do
|
|
125
112
|
end
|
126
113
|
|
127
114
|
context 'when called with Rack environment hash' do
|
128
|
-
let(:env) {
|
129
|
-
{
|
130
|
-
'REQUEST_METHOD' => 'GET',
|
131
|
-
'PATH_INFO' => '/path',
|
132
|
-
'QUERY_STRING' => 'foo=bar'
|
133
|
-
}
|
134
|
-
}
|
115
|
+
let(:env) { { 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/path', 'QUERY_STRING' => 'foo=bar' } }
|
135
116
|
|
136
117
|
context "when env['REQUEST_URI'] is nil" do
|
137
118
|
before { env['REQUEST_URI'] = nil }
|
@@ -6,9 +6,7 @@ if active_record?
|
|
6
6
|
describe Bullet::Detector::Association, 'has_many' do
|
7
7
|
context 'post => comments' do
|
8
8
|
it 'should detect non preload post => comments' do
|
9
|
-
Post.all.each
|
10
|
-
post.comments.map(&:name)
|
11
|
-
end
|
9
|
+
Post.all.each { |post| post.comments.map(&:name) }
|
12
10
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
13
11
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
14
12
|
|
@@ -16,9 +14,7 @@ if active_record?
|
|
16
14
|
end
|
17
15
|
|
18
16
|
it 'should detect non preload post => comments for find_by_sql' do
|
19
|
-
Post.find_by_sql('SELECT * FROM posts').each
|
20
|
-
post.comments.map(&:name)
|
21
|
-
end
|
17
|
+
Post.find_by_sql('SELECT * FROM posts').each { |post| post.comments.map(&:name) }
|
22
18
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
23
19
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
24
20
|
|
@@ -26,9 +22,7 @@ if active_record?
|
|
26
22
|
end
|
27
23
|
|
28
24
|
it 'should detect preload with post => comments' do
|
29
|
-
Post.includes(:comments).each
|
30
|
-
post.comments.map(&:name)
|
31
|
-
end
|
25
|
+
Post.includes(:comments).each { |post| post.comments.map(&:name) }
|
32
26
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
33
27
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
34
28
|
|
@@ -65,9 +59,7 @@ if active_record?
|
|
65
59
|
end
|
66
60
|
|
67
61
|
it 'should detect non preload post => comments with empty?' do
|
68
|
-
Post.all.each
|
69
|
-
post.comments.empty?
|
70
|
-
end
|
62
|
+
Post.all.each { |post| post.comments.empty? }
|
71
63
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
72
64
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
73
65
|
|
@@ -76,9 +68,7 @@ if active_record?
|
|
76
68
|
|
77
69
|
it 'should detect non preload post => comments with include?' do
|
78
70
|
comment = Comment.last
|
79
|
-
Post.all.each
|
80
|
-
post.comments.include?(comment)
|
81
|
-
end
|
71
|
+
Post.all.each { |post| post.comments.include?(comment) }
|
82
72
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
83
73
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
84
74
|
|
@@ -86,9 +76,7 @@ if active_record?
|
|
86
76
|
end
|
87
77
|
|
88
78
|
it 'should not detect unused preload person => pets with empty?' do
|
89
|
-
Person.all.each
|
90
|
-
person.pets.empty?
|
91
|
-
end
|
79
|
+
Person.all.each { |person| person.pets.empty? }
|
92
80
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
93
81
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
94
82
|
|
@@ -98,11 +86,7 @@ if active_record?
|
|
98
86
|
|
99
87
|
context 'category => posts => comments' do
|
100
88
|
it 'should detect non preload category => posts => comments' do
|
101
|
-
Category.all.each
|
102
|
-
category.posts.each do |post|
|
103
|
-
post.comments.map(&:name)
|
104
|
-
end
|
105
|
-
end
|
89
|
+
Category.all.each { |category| category.posts.each { |post| post.comments.map(&:name) } }
|
106
90
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
107
91
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
108
92
|
|
@@ -111,11 +95,7 @@ if active_record?
|
|
111
95
|
end
|
112
96
|
|
113
97
|
it 'should detect preload category => posts, but no post => comments' do
|
114
|
-
Category.includes(:posts).each
|
115
|
-
category.posts.each do |post|
|
116
|
-
post.comments.map(&:name)
|
117
|
-
end
|
118
|
-
end
|
98
|
+
Category.includes(:posts).each { |category| category.posts.each { |post| post.comments.map(&:name) } }
|
119
99
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
120
100
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
121
101
|
|
@@ -124,11 +104,7 @@ if active_record?
|
|
124
104
|
end
|
125
105
|
|
126
106
|
it 'should detect preload with category => posts => comments' do
|
127
|
-
Category.includes(posts: :comments).each
|
128
|
-
category.posts.each do |post|
|
129
|
-
post.comments.map(&:name)
|
130
|
-
end
|
131
|
-
end
|
107
|
+
Category.includes(posts: :comments).each { |category| category.posts.each { |post| post.comments.map(&:name) } }
|
132
108
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
133
109
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
134
110
|
|
@@ -137,9 +113,7 @@ if active_record?
|
|
137
113
|
|
138
114
|
it 'should detect preload with category => posts => comments with posts.id > 0' do
|
139
115
|
Category.includes(posts: :comments).where('posts.id > 0').references(:posts).each do |category|
|
140
|
-
category.posts.each
|
141
|
-
post.comments.map(&:name)
|
142
|
-
end
|
116
|
+
category.posts.each { |post| post.comments.map(&:name) }
|
143
117
|
end
|
144
118
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
145
119
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
@@ -156,9 +130,7 @@ if active_record?
|
|
156
130
|
end
|
157
131
|
|
158
132
|
it 'should detect unused preload with post => commnets, no category => posts' do
|
159
|
-
Category.includes(posts: :comments).each
|
160
|
-
category.posts.map(&:name)
|
161
|
-
end
|
133
|
+
Category.includes(posts: :comments).each { |category| category.posts.map(&:name) }
|
162
134
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
163
135
|
expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
|
164
136
|
|
@@ -212,9 +184,7 @@ if active_record?
|
|
212
184
|
end
|
213
185
|
|
214
186
|
it 'should detect unused preload with category => entries, but not with category => posts' do
|
215
|
-
Category.includes(%i[posts entries]).each
|
216
|
-
category.posts.map(&:name)
|
217
|
-
end
|
187
|
+
Category.includes(%i[posts entries]).each { |category| category.posts.map(&:name) }
|
218
188
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
219
189
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Category, :posts)
|
220
190
|
expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Category, :entries)
|
@@ -225,9 +195,7 @@ if active_record?
|
|
225
195
|
|
226
196
|
context 'post => comment' do
|
227
197
|
it 'should detect unused preload with post => comments' do
|
228
|
-
Post.includes(:comments).each
|
229
|
-
post.comments.first&.name
|
230
|
-
end
|
198
|
+
Post.includes(:comments).each { |post| post.comments.first&.name }
|
231
199
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
232
200
|
expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
|
233
201
|
|
@@ -246,7 +214,7 @@ if active_record?
|
|
246
214
|
category = Category.first
|
247
215
|
category.draft_post.destroy!
|
248
216
|
post = category.draft_post
|
249
|
-
post.
|
217
|
+
post.update!(link: true)
|
250
218
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
251
219
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
252
220
|
|
@@ -272,9 +240,7 @@ if active_record?
|
|
272
240
|
|
273
241
|
context 'scope for_category_name' do
|
274
242
|
it 'should detect preload with post => category' do
|
275
|
-
Post.in_category_name('first').references(:categories).each
|
276
|
-
post.category.name
|
277
|
-
end
|
243
|
+
Post.in_category_name('first').references(:categories).each { |post| post.category.name }
|
278
244
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
279
245
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
280
246
|
|
@@ -292,9 +258,7 @@ if active_record?
|
|
292
258
|
|
293
259
|
context 'scope preload_comments' do
|
294
260
|
it 'should detect preload post => comments with scope' do
|
295
|
-
Post.preload_comments.each
|
296
|
-
post.comments.map(&:name)
|
297
|
-
end
|
261
|
+
Post.preload_comments.each { |post| post.comments.map(&:name) }
|
298
262
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
299
263
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
300
264
|
|
@@ -314,9 +278,7 @@ if active_record?
|
|
314
278
|
describe Bullet::Detector::Association, 'belongs_to' do
|
315
279
|
context 'comment => post' do
|
316
280
|
it 'should detect non preload with comment => post' do
|
317
|
-
Comment.all.each
|
318
|
-
comment.post.name
|
319
|
-
end
|
281
|
+
Comment.all.each { |comment| comment.post.name }
|
320
282
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
321
283
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
322
284
|
|
@@ -331,10 +293,8 @@ if active_record?
|
|
331
293
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
332
294
|
end
|
333
295
|
|
334
|
-
it 'should
|
335
|
-
Comment.includes(:post).each
|
336
|
-
comment.post.name
|
337
|
-
end
|
296
|
+
it 'should detect preload with comment => post' do
|
297
|
+
Comment.includes(:post).each { |comment| comment.post.name }
|
338
298
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
339
299
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
340
300
|
|
@@ -362,29 +322,16 @@ if active_record?
|
|
362
322
|
|
363
323
|
new_post.trigger_after_save = true
|
364
324
|
new_post.save!
|
325
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
365
326
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
366
327
|
|
367
328
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
368
329
|
end
|
369
|
-
|
370
|
-
it 'should not detect "manual" preload' do
|
371
|
-
comment = Comment.all.to_a.first
|
372
|
-
post = Post.find(comment.post_id)
|
373
|
-
# "manually" preload with out-of-band data
|
374
|
-
comment.post = post
|
375
|
-
# loading it should not trigger anything
|
376
|
-
comment.post
|
377
|
-
|
378
|
-
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
379
|
-
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
380
|
-
end
|
381
330
|
end
|
382
331
|
|
383
332
|
context 'comment => post => category' do
|
384
333
|
it 'should detect non preload association with comment => post' do
|
385
|
-
Comment.all.each
|
386
|
-
comment.post.category.name
|
387
|
-
end
|
334
|
+
Comment.all.each { |comment| comment.post.category.name }
|
388
335
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
389
336
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
390
337
|
|
@@ -401,9 +348,7 @@ if active_record?
|
|
401
348
|
end
|
402
349
|
|
403
350
|
it 'should detect non preload association with post => category' do
|
404
|
-
Comment.includes(:post).each
|
405
|
-
comment.post.category.name
|
406
|
-
end
|
351
|
+
Comment.includes(:post).each { |comment| comment.post.category.name }
|
407
352
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
408
353
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
409
354
|
|
@@ -411,9 +356,7 @@ if active_record?
|
|
411
356
|
end
|
412
357
|
|
413
358
|
it 'should not detect unpreload association' do
|
414
|
-
Comment.includes(post: :category).each
|
415
|
-
comment.post.category.name
|
416
|
-
end
|
359
|
+
Comment.includes(post: :category).each { |comment| comment.post.category.name }
|
417
360
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
418
361
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
419
362
|
|
@@ -423,9 +366,8 @@ if active_record?
|
|
423
366
|
|
424
367
|
context 'comment => author, post => writer' do
|
425
368
|
it 'should detect non preloaded writer' do
|
426
|
-
Comment.includes(%i[author post]).where(['base_users.id = ?', BaseUser.first]).references(:base_users)
|
427
|
-
comment.post.writer.name
|
428
|
-
end
|
369
|
+
Comment.includes(%i[author post]).where(['base_users.id = ?', BaseUser.first]).references(:base_users)
|
370
|
+
.each { |comment| comment.post.writer.name }
|
429
371
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
430
372
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
431
373
|
|
@@ -433,9 +375,10 @@ if active_record?
|
|
433
375
|
end
|
434
376
|
|
435
377
|
it 'should detect unused preload with comment => author' do
|
436
|
-
Comment.includes([:author, { post: :writer }]).where(['base_users.id = ?', BaseUser.first]).references(
|
437
|
-
|
438
|
-
|
378
|
+
Comment.includes([:author, { post: :writer }]).where(['base_users.id = ?', BaseUser.first]).references(
|
379
|
+
:base_users
|
380
|
+
)
|
381
|
+
.each { |comment| comment.post.writer.name }
|
439
382
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
440
383
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
441
384
|
|
@@ -453,11 +396,7 @@ if active_record?
|
|
453
396
|
end
|
454
397
|
|
455
398
|
it 'should not raise a stack error from posts to category' do
|
456
|
-
expect {
|
457
|
-
Comment.includes(post: :category).each do |com|
|
458
|
-
com.post.category
|
459
|
-
end
|
460
|
-
}.not_to raise_error
|
399
|
+
expect { Comment.includes(post: :category).each { |com| com.post.category } }.not_to raise_error
|
461
400
|
end
|
462
401
|
end
|
463
402
|
end
|
@@ -465,9 +404,7 @@ if active_record?
|
|
465
404
|
describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
|
466
405
|
context 'students <=> teachers' do
|
467
406
|
it 'should detect non preload associations' do
|
468
|
-
Student.all.each
|
469
|
-
student.teachers.map(&:name)
|
470
|
-
end
|
407
|
+
Student.all.each { |student| student.teachers.map(&:name) }
|
471
408
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
472
409
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
473
410
|
|
@@ -475,9 +412,7 @@ if active_record?
|
|
475
412
|
end
|
476
413
|
|
477
414
|
it 'should detect preload associations' do
|
478
|
-
Student.includes(:teachers).each
|
479
|
-
student.teachers.map(&:name)
|
480
|
-
end
|
415
|
+
Student.includes(:teachers).each { |student| student.teachers.map(&:name) }
|
481
416
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
482
417
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
483
418
|
|
@@ -501,9 +436,7 @@ if active_record?
|
|
501
436
|
end
|
502
437
|
|
503
438
|
it 'should detect non preload student => teachers with empty?' do
|
504
|
-
Student.all.each
|
505
|
-
student.teachers.empty?
|
506
|
-
end
|
439
|
+
Student.all.each { |student| student.teachers.empty? }
|
507
440
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
508
441
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
509
442
|
|
@@ -515,9 +448,7 @@ if active_record?
|
|
515
448
|
describe Bullet::Detector::Association, 'has_many :through' do
|
516
449
|
context 'firm => clients' do
|
517
450
|
it 'should detect non preload associations' do
|
518
|
-
Firm.all.each
|
519
|
-
firm.clients.map(&:name)
|
520
|
-
end
|
451
|
+
Firm.all.each { |firm| firm.clients.map(&:name) }
|
521
452
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
522
453
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
523
454
|
|
@@ -525,9 +456,7 @@ if active_record?
|
|
525
456
|
end
|
526
457
|
|
527
458
|
it 'should detect preload associations' do
|
528
|
-
Firm.includes(:clients).each
|
529
|
-
firm.clients.map(&:name)
|
530
|
-
end
|
459
|
+
Firm.includes(:clients).each { |firm| firm.clients.map(&:name) }
|
531
460
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
532
461
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
533
462
|
|
@@ -553,9 +482,7 @@ if active_record?
|
|
553
482
|
|
554
483
|
context 'firm => clients => groups' do
|
555
484
|
it 'should detect non preload associations' do
|
556
|
-
Firm.all.each
|
557
|
-
firm.groups.map(&:name)
|
558
|
-
end
|
485
|
+
Firm.all.each { |firm| firm.groups.map(&:name) }
|
559
486
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
560
487
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
561
488
|
|
@@ -563,9 +490,7 @@ if active_record?
|
|
563
490
|
end
|
564
491
|
|
565
492
|
it 'should detect preload associations' do
|
566
|
-
Firm.includes(:groups).each
|
567
|
-
firm.groups.map(&:name)
|
568
|
-
end
|
493
|
+
Firm.includes(:groups).each { |firm| firm.groups.map(&:name) }
|
569
494
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
570
495
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
571
496
|
|
@@ -593,9 +518,7 @@ if active_record?
|
|
593
518
|
describe Bullet::Detector::Association, 'has_one' do
|
594
519
|
context 'company => address' do
|
595
520
|
it 'should detect non preload association' do
|
596
|
-
Company.all.each
|
597
|
-
company.address.name
|
598
|
-
end
|
521
|
+
Company.all.each { |company| company.address.name }
|
599
522
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
600
523
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
601
524
|
|
@@ -603,9 +526,7 @@ if active_record?
|
|
603
526
|
end
|
604
527
|
|
605
528
|
it 'should detect preload association' do
|
606
|
-
Company.includes(:address).each
|
607
|
-
company.address.name
|
608
|
-
end
|
529
|
+
Company.includes(:address).each { |company| company.address.name }
|
609
530
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
610
531
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
611
532
|
|
@@ -699,9 +620,7 @@ if active_record?
|
|
699
620
|
describe Bullet::Detector::Association, 'STI' do
|
700
621
|
context 'page => author' do
|
701
622
|
it 'should detect non preload associations' do
|
702
|
-
Page.all.each
|
703
|
-
page.author.name
|
704
|
-
end
|
623
|
+
Page.all.each { |page| page.author.name }
|
705
624
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
706
625
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
707
626
|
|
@@ -709,9 +628,7 @@ if active_record?
|
|
709
628
|
end
|
710
629
|
|
711
630
|
it 'should detect preload associations' do
|
712
|
-
Page.includes(:author).each
|
713
|
-
page.author.name
|
714
|
-
end
|
631
|
+
Page.includes(:author).each { |page| page.author.name }
|
715
632
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
716
633
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
717
634
|
|
@@ -740,9 +657,7 @@ if active_record?
|
|
740
657
|
after { Bullet.n_plus_one_query_enable = true }
|
741
658
|
|
742
659
|
it 'should not detect n plus one query' do
|
743
|
-
Post.all.each
|
744
|
-
post.comments.map(&:name)
|
745
|
-
end
|
660
|
+
Post.all.each { |post| post.comments.map(&:name) }
|
746
661
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
747
662
|
|
748
663
|
expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
|
@@ -771,9 +686,7 @@ if active_record?
|
|
771
686
|
end
|
772
687
|
|
773
688
|
it 'should still detect n plus one query' do
|
774
|
-
Post.all.each
|
775
|
-
post.comments.map(&:name)
|
776
|
-
end
|
689
|
+
Post.all.each { |post| post.comments.map(&:name) }
|
777
690
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
778
691
|
|
779
692
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|
@@ -786,9 +699,7 @@ if active_record?
|
|
786
699
|
after { Bullet.clear_whitelist }
|
787
700
|
|
788
701
|
it 'should not detect n plus one query' do
|
789
|
-
Post.all.each
|
790
|
-
post.comments.map(&:name)
|
791
|
-
end
|
702
|
+
Post.all.each { |post| post.comments.map(&:name) }
|
792
703
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
793
704
|
|
794
705
|
expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
|
@@ -817,9 +728,7 @@ if active_record?
|
|
817
728
|
end
|
818
729
|
|
819
730
|
it 'should still detect n plus one query' do
|
820
|
-
Post.all.each
|
821
|
-
post.comments.map(&:name)
|
822
|
-
end
|
731
|
+
Post.all.each { |post| post.comments.map(&:name) }
|
823
732
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
824
733
|
|
825
734
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
|