bullet 5.8.1 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +22 -1
  3. data/CHANGELOG.md +24 -1
  4. data/Gemfile.mongoid-7.0 +15 -0
  5. data/Gemfile.rails-4.0 +1 -1
  6. data/Gemfile.rails-4.1 +1 -1
  7. data/Gemfile.rails-4.2 +1 -1
  8. data/Gemfile.rails-5.0 +1 -1
  9. data/Gemfile.rails-5.1 +1 -1
  10. data/Gemfile.rails-5.2 +1 -1
  11. data/Gemfile.rails-6.0 +15 -0
  12. data/README.md +24 -10
  13. data/lib/bullet.rb +42 -17
  14. data/lib/bullet/active_job.rb +9 -0
  15. data/lib/bullet/active_record4.rb +9 -32
  16. data/lib/bullet/active_record41.rb +7 -27
  17. data/lib/bullet/active_record42.rb +8 -24
  18. data/lib/bullet/active_record5.rb +188 -179
  19. data/lib/bullet/active_record52.rb +176 -168
  20. data/lib/bullet/active_record60.rb +267 -0
  21. data/lib/bullet/bullet_xhr.js +63 -0
  22. data/lib/bullet/dependency.rb +48 -34
  23. data/lib/bullet/detector/association.rb +26 -20
  24. data/lib/bullet/detector/base.rb +1 -2
  25. data/lib/bullet/detector/counter_cache.rb +13 -9
  26. data/lib/bullet/detector/n_plus_one_query.rb +22 -12
  27. data/lib/bullet/detector/unused_eager_loading.rb +6 -3
  28. data/lib/bullet/ext/object.rb +4 -2
  29. data/lib/bullet/mongoid4x.rb +2 -6
  30. data/lib/bullet/mongoid5x.rb +2 -6
  31. data/lib/bullet/mongoid6x.rb +2 -6
  32. data/lib/bullet/mongoid7x.rb +57 -0
  33. data/lib/bullet/notification/base.rb +14 -18
  34. data/lib/bullet/notification/n_plus_one_query.rb +2 -4
  35. data/lib/bullet/notification/unused_eager_loading.rb +2 -4
  36. data/lib/bullet/rack.rb +39 -20
  37. data/lib/bullet/stack_trace_filter.rb +6 -12
  38. data/lib/bullet/version.rb +1 -1
  39. data/lib/generators/bullet/install_generator.rb +4 -2
  40. data/perf/benchmark.rb +8 -14
  41. data/spec/bullet/detector/counter_cache_spec.rb +5 -5
  42. data/spec/bullet/detector/n_plus_one_query_spec.rb +7 -3
  43. data/spec/bullet/detector/unused_eager_loading_spec.rb +29 -12
  44. data/spec/bullet/ext/object_spec.rb +9 -4
  45. data/spec/bullet/notification/base_spec.rb +1 -3
  46. data/spec/bullet/notification/n_plus_one_query_spec.rb +18 -3
  47. data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
  48. data/spec/bullet/rack_spec.rb +30 -6
  49. data/spec/bullet/registry/association_spec.rb +2 -2
  50. data/spec/bullet/registry/base_spec.rb +1 -1
  51. data/spec/bullet_spec.rb +10 -29
  52. data/spec/integration/active_record/association_spec.rb +45 -136
  53. data/spec/integration/counter_cache_spec.rb +11 -31
  54. data/spec/integration/mongoid/association_spec.rb +18 -32
  55. data/spec/models/folder.rb +1 -2
  56. data/spec/models/group.rb +1 -2
  57. data/spec/models/page.rb +1 -2
  58. data/spec/models/writer.rb +1 -2
  59. data/spec/spec_helper.rb +6 -10
  60. data/spec/support/bullet_ext.rb +8 -9
  61. data/spec/support/mongo_seed.rb +2 -16
  62. data/test.sh +2 -0
  63. data/update.sh +1 -0
  64. 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([:association]))).to be_empty
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([:association]))).to eq([:association])
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([:association]))).to be_empty
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([:association]))).to eq([:association])
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(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
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) { ['/dir1', '/dir1/subdir'] }
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', [:association])
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(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
57
- expect(UnusedEagerLoading).not_to receive(:create_notification).with('Post', [:association])
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([@post.bullet_key, @post2.bullet_key], :associations)
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([@post.bullet_key, @post2.bullet_key], :association1)
72
- expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association2)
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 'primary_key_value' do
20
+ context 'bullet_primary_key_value' do
21
21
  it 'should return id' do
22
22
  post = Post.first
23
- expect(post.primary_key_value).to eq(post.id)
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.primary_key_value).to eq(post.name)
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.primary_key_value).to eq("#{post.category_id},#{post.writer_id}")
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') do
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 { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n") }
11
- it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n"]) }
12
- it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]") }
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 { expect(subject.body).to eq(" Post => [:comments, :votes]\n Remove from your finder: :includes => [:comments, :votes]") }
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
@@ -45,9 +45,9 @@ module Bullet
45
45
  expect(middleware).not_to be_empty(response)
46
46
  end
47
47
 
48
- it 'should be true if response is not found' do
48
+ it 'should be false if response is not found' do
49
49
  response = ['Not Found']
50
- expect(middleware).to be_empty(response)
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
- status, headers, response = middleware.call('Content-Type' => 'text/html')
74
+ _, headers, response = middleware.call('Content-Type' => 'text/html')
73
75
  expect(headers['Content-Length']).to eq('56')
74
- expect(response).to eq(['<html><head></head><body><bullet></bullet></body></html>'])
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
- status, headers, response = middleware.call('Content-Type' => 'text/html')
84
- expect(headers['Content-Length']).to eq('58')
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(['value']))).to eq(%w[key1 key2])
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(['value']))).to be_empty
23
+ expect(subject.similarly_associated('key3', Set.new(%w[value]))).to be_empty
24
24
  end
25
25
  end
26
26
  end
@@ -9,7 +9,7 @@ module Bullet
9
9
 
10
10
  context '#[]' do
11
11
  it 'should get value by key' do
12
- expect(subject['key']).to eq(Set.new(['value']))
12
+ expect(subject['key']).to eq(Set.new(%w[value]))
13
13
  end
14
14
  end
15
15
 
@@ -17,9 +17,7 @@ describe Bullet, focused: true do
17
17
  end
18
18
 
19
19
  context 'disable Bullet' do
20
- before do
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? Bullet::Mongoid
31
- expect(Bullet::ActiveRecord).not_to receive(:enable) if defined? Bullet::ActiveRecord
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) do
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) do
57
- $stdout = StringIO.new
58
- end
52
+ before(:each) { $stdout = StringIO.new }
59
53
 
60
- after(:each) do
61
- $stdout = STDOUT
62
- end
54
+ after(:each) { $stdout = STDOUT }
63
55
 
64
56
  context 'when debug is enabled' do
65
- before(:each) do
66
- ENV['BULLET_DEBUG'] = 'true'
67
- end
57
+ before(:each) { ENV['BULLET_DEBUG'] = 'true' }
68
58
 
69
- after(:each) do
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 do |post|
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 do |post|
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 do |post|
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 do |post|
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 do |post|
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 do |person|
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 do |category|
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 do |category|
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 do |category|
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 do |post|
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 do |category|
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 do |category|
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 do |post|
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.update_attributes!(link: true)
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 do |post|
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 do |post|
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 do |comment|
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 dtect preload with comment => post' do
335
- Comment.includes(:post).each do |comment|
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 do |comment|
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 do |comment|
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 do |comment|
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).each do |comment|
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(:base_users).each do |comment|
437
- comment.post.writer.name
438
- end
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 do |student|
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 do |student|
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 do |student|
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 do |firm|
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 do |firm|
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 do |firm|
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 do |firm|
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 do |company|
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 do |company|
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 do |page|
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 do |page|
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 do |post|
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 do |post|
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 do |post|
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 do |post|
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)