bullet 4.9.0 → 4.10.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +1 -3
  6. data/Gemfile.mongoid +2 -3
  7. data/Gemfile.mongoid-2.4 +0 -3
  8. data/Gemfile.mongoid-2.5 +0 -3
  9. data/Gemfile.mongoid-2.6 +0 -3
  10. data/Gemfile.mongoid-2.7 +0 -3
  11. data/Gemfile.mongoid-2.8 +0 -3
  12. data/Gemfile.mongoid-3.0 +0 -3
  13. data/Gemfile.mongoid-3.1 +0 -3
  14. data/Gemfile.mongoid-4.0 +19 -0
  15. data/Gemfile.rails-3.0 +0 -2
  16. data/Gemfile.rails-3.1 +1 -3
  17. data/Gemfile.rails-3.2 +1 -3
  18. data/Gemfile.rails-4.0 +1 -3
  19. data/Gemfile.rails-4.1 +1 -3
  20. data/README.md +19 -2
  21. data/bullet.gemspec +4 -2
  22. data/lib/bullet.rb +39 -10
  23. data/lib/bullet/active_record3.rb +20 -2
  24. data/lib/bullet/active_record3x.rb +20 -2
  25. data/lib/bullet/active_record4.rb +20 -2
  26. data/lib/bullet/active_record41.rb +20 -2
  27. data/lib/bullet/detector/association.rb +14 -25
  28. data/lib/bullet/detector/base.rb +0 -6
  29. data/lib/bullet/detector/counter_cache.rb +10 -12
  30. data/lib/bullet/detector/n_plus_one_query.rb +12 -8
  31. data/lib/bullet/detector/unused_eager_loading.rb +5 -1
  32. data/lib/bullet/mongoid3x.rb +5 -4
  33. data/lib/bullet/mongoid4x.rb +5 -4
  34. data/lib/bullet/version.rb +1 -1
  35. data/spec/bullet/detector/association_spec.rb +0 -19
  36. data/spec/bullet/detector/base_spec.rb +0 -6
  37. data/spec/bullet/detector/counter_cache_spec.rb +0 -8
  38. data/spec/bullet/detector/n_plus_one_query_spec.rb +0 -6
  39. data/spec/bullet/detector/unused_eager_loading_spec.rb +0 -7
  40. data/spec/bullet/rack_spec.rb +1 -7
  41. data/spec/bullet/registry/object_spec.rb +0 -1
  42. data/spec/bullet_spec.rb +41 -0
  43. data/spec/integration/active_record3/association_spec.rb +18 -75
  44. data/spec/integration/active_record4/association_spec.rb +16 -75
  45. data/spec/integration/counter_cache_spec.rb +1 -1
  46. data/spec/integration/mongoid/association_spec.rb +0 -10
  47. data/spec/spec_helper.rb +17 -0
  48. data/spec/support/mongo_seed.rb +1 -1
  49. data/test.sh +1 -0
  50. metadata +7 -3
@@ -57,16 +57,10 @@ module Bullet
57
57
 
58
58
  context "#call" do
59
59
  context "when Bullet is enabled" do
60
- it "should invoke Bullet.start_request and Bullet.end_request" do
61
- expect(Bullet).to receive(:start_request)
62
- expect(Bullet).to receive(:end_request)
63
- middleware.call([])
64
- end
65
-
66
60
  it "should return original response body" do
67
61
  expected_response = Support::ResponseDouble.new "Actual body"
68
62
  app.response = expected_response
69
- status, headers, response = middleware.call([])
63
+ _, _, response = middleware.call([])
70
64
  expect(response).to eq(expected_response)
71
65
  end
72
66
 
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
-
4
3
  module Bullet
5
4
  module Registry
6
5
  describe Object do
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bullet, focused: true do
4
+ subject { Bullet }
5
+
6
+ describe '#enable' do
7
+
8
+ context 'enable Bullet' do
9
+ before do
10
+ # Bullet.enable
11
+ # Do nothing. Bullet has already been enabled for the whole test suite.
12
+ end
13
+
14
+ it 'should be enabled' do
15
+ expect(subject).to be_enable
16
+ end
17
+
18
+ context 'disable Bullet' do
19
+ before do
20
+ Bullet.enable = false
21
+ end
22
+
23
+ it 'should be disabled' do
24
+ expect(subject).to_not be_enable
25
+ end
26
+
27
+ context 'enable Bullet again without patching again the orms' do
28
+ before do
29
+ Bullet::Mongoid.should_not_receive(:enable) if defined? Bullet::Mongoid
30
+ Bullet::ActiveRecord.should_not_receive(:enable) if defined? Bullet::ActiveRecord
31
+ Bullet.enable = true
32
+ end
33
+
34
+ it 'should be enabled again' do
35
+ expect(subject).to be_enable
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,16 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- if active_record3?
3
+ if !mongoid? && active_record3?
4
4
  describe Bullet::Detector::Association, 'has_many' do
5
- before(:each) do
6
- Bullet.clear
7
- Bullet.start_request
8
- end
9
-
10
- after(:each) do
11
- Bullet.end_request
12
- end
13
-
14
5
  context "post => comments" do
15
6
  it "should detect non preload post => comments" do
16
7
  Post.all.each do |post|
@@ -101,6 +92,18 @@ if active_record3?
101
92
  expect(Bullet::Detector::Association).to be_completely_preloading_associations
102
93
  end
103
94
 
95
+ it "should detect preload with category => posts => comments with posts.id > 0" do
96
+ Category.includes({:posts => :comments}).where('posts.id > 0').each do |category|
97
+ category.posts.each do |post|
98
+ post.comments.map(&:name)
99
+ end
100
+ end
101
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
102
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
103
+
104
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
105
+ end
106
+
104
107
  it "should detect unused preload with category => posts => comments" do
105
108
  Category.includes({:posts => :comments}).map(&:name)
106
109
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
@@ -207,6 +210,8 @@ if active_record3?
207
210
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
208
211
  expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Category, :posts)
209
212
  expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :writer)
213
+
214
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
210
215
  end
211
216
  end
212
217
 
@@ -252,15 +257,6 @@ if active_record3?
252
257
  end
253
258
 
254
259
  describe Bullet::Detector::Association, 'belongs_to' do
255
- before(:each) do
256
- Bullet.clear
257
- Bullet.start_request
258
- end
259
-
260
- after(:each) do
261
- Bullet.end_request
262
- end
263
-
264
260
  context "comment => post" do
265
261
  it "should detect non preload with comment => post" do
266
262
  Comment.all.each do |comment|
@@ -340,8 +336,6 @@ if active_record3?
340
336
  end
341
337
 
342
338
  context "comment => author, post => writer" do
343
- # this happens because the post isn't a possible object even though the writer is access through the post
344
- # which leads to an 1+N queries
345
339
  it "should detect non preloaded writer" do
346
340
  Comment.includes([:author, :post]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
347
341
  comment.post.writer.name
@@ -352,32 +346,26 @@ if active_record3?
352
346
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :writer)
353
347
  end
354
348
 
355
- # this happens because the comment doesn't break down the hash into keys
356
- # properly creating an association from comment to post
357
349
  it "should detect unused preload with comment => author" do
358
350
  Comment.includes([:author, {:post => :writer}]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
359
351
  comment.post.writer.name
360
352
  end
361
353
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
362
- expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Comment, :author)
354
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
363
355
 
364
356
  expect(Bullet::Detector::Association).to be_completely_preloading_associations
365
357
  end
366
358
 
367
- # To flyerhzm: This does not detect that newspaper is unpreloaded. The association is
368
- # not within possible objects, and thus cannot be detected as unpreloaded
369
359
  it "should detect non preloading with writer => newspaper" do
370
360
  Comment.all(:include => {:post => :writer}, :conditions => "posts.name like '%first%'").each do |comment|
371
361
  comment.post.writer.newspaper.name
372
362
  end
373
- #Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
374
- #Bullet::Detector::Association.should_not be_has_unused_preload_associations
363
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
364
+ Bullet::Detector::Association.should_not be_has_unused_preload_associations
375
365
 
376
366
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Writer, :newspaper)
377
367
  end
378
368
 
379
- # when we attempt to access category, there is an infinite overflow because load_target is hijacked leading to
380
- # a repeating loop of calls in this test
381
369
  it "should not raise a stack error from posts to category" do
382
370
  expect {
383
371
  Comment.includes({:post => :category}).each do |com|
@@ -389,15 +377,6 @@ if active_record3?
389
377
  end
390
378
 
391
379
  describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
392
- before(:each) do
393
- Bullet.clear
394
- Bullet.start_request
395
- end
396
-
397
- after(:each) do
398
- Bullet.end_request
399
- end
400
-
401
380
  context "students <=> teachers" do
402
381
  it "should detect non preload associations" do
403
382
  Student.all.each do |student|
@@ -438,15 +417,6 @@ if active_record3?
438
417
  end
439
418
 
440
419
  describe Bullet::Detector::Association, 'has_many :through' do
441
- before(:each) do
442
- Bullet.clear
443
- Bullet.start_request
444
- end
445
-
446
- after(:each) do
447
- Bullet.end_request
448
- end
449
-
450
420
  context "firm => clients" do
451
421
  it "should detect non preload associations" do
452
422
  Firm.all.each do |firm|
@@ -487,15 +457,6 @@ if active_record3?
487
457
  end
488
458
 
489
459
  describe Bullet::Detector::Association, "has_one" do
490
- before(:each) do
491
- Bullet.clear
492
- Bullet.start_request
493
- end
494
-
495
- after(:each) do
496
- Bullet.end_request
497
- end
498
-
499
460
  context "company => address" do
500
461
  it "should detect non preload association" do
501
462
  Company.all.each do |company|
@@ -536,15 +497,6 @@ if active_record3?
536
497
  end
537
498
 
538
499
  describe Bullet::Detector::Association, "call one association that in possible objects" do
539
- before(:each) do
540
- Bullet.clear
541
- Bullet.start_request
542
- end
543
-
544
- after(:each) do
545
- Bullet.end_request
546
- end
547
-
548
500
  it "should not detect preload association" do
549
501
  Post.all
550
502
  Post.first.comments.map(&:name)
@@ -556,15 +508,6 @@ if active_record3?
556
508
  end
557
509
 
558
510
  describe Bullet::Detector::Association, "STI" do
559
- before(:each) do
560
- Bullet.clear
561
- Bullet.start_request
562
- end
563
-
564
- after(:each) do
565
- Bullet.end_request
566
- end
567
-
568
511
  context "page => author" do
569
512
  it "should detect non preload associations" do
570
513
  Page.all.each do |page|
@@ -1,16 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- if active_record4?
3
+ if !mongoid? && active_record4?
4
4
  describe Bullet::Detector::Association, 'has_many' do
5
- before(:each) do
6
- Bullet.clear
7
- Bullet.start_request
8
- end
9
-
10
- after(:each) do
11
- Bullet.end_request
12
- end
13
-
14
5
  context "post => comments" do
15
6
  it "should detect non preload post => comments" do
16
7
  Post.all.each do |post|
@@ -101,6 +92,18 @@ if active_record4?
101
92
  expect(Bullet::Detector::Association).to be_completely_preloading_associations
102
93
  end
103
94
 
95
+ it "should detect preload with category => posts => comments with posts.id > 0" do
96
+ Category.includes({:posts => :comments}).where('posts.id > 0').references(:posts).each do |category|
97
+ category.posts.each do |post|
98
+ post.comments.map(&:name)
99
+ end
100
+ end
101
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
102
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
103
+
104
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
105
+ end
106
+
104
107
  it "should detect unused preload with category => posts => comments" do
105
108
  Category.includes({:posts => :comments}).map(&:name)
106
109
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
@@ -252,15 +255,6 @@ if active_record4?
252
255
  end
253
256
 
254
257
  describe Bullet::Detector::Association, 'belongs_to' do
255
- before(:each) do
256
- Bullet.clear
257
- Bullet.start_request
258
- end
259
-
260
- after(:each) do
261
- Bullet.end_request
262
- end
263
-
264
258
  context "comment => post" do
265
259
  it "should detect non preload with comment => post" do
266
260
  Comment.all.each do |comment|
@@ -340,8 +334,6 @@ if active_record4?
340
334
  end
341
335
 
342
336
  context "comment => author, post => writer" do
343
- # this happens because the post isn't a possible object even though the writer is access through the post
344
- # which leads to an 1+N queries
345
337
  it "should detect non preloaded writer" do
346
338
  Comment.includes([:author, :post]).where(["base_users.id = ?", BaseUser.first]).references(:base_users).each do |comment|
347
339
  comment.post.writer.name
@@ -352,32 +344,26 @@ if active_record4?
352
344
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :writer)
353
345
  end
354
346
 
355
- # this happens because the comment doesn't break down the hash into keys
356
- # properly creating an association from comment to post
357
347
  it "should detect unused preload with comment => author" do
358
348
  Comment.includes([:author, {:post => :writer}]).where(["base_users.id = ?", BaseUser.first]).references(:base_users).each do |comment|
359
349
  comment.post.writer.name
360
350
  end
361
351
  Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
362
- expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Comment, :author)
352
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
363
353
 
364
354
  expect(Bullet::Detector::Association).to be_completely_preloading_associations
365
355
  end
366
356
 
367
- # To flyerhzm: This does not detect that newspaper is unpreloaded. The association is
368
- # not within possible objects, and thus cannot be detected as unpreloaded
369
357
  it "should detect non preloading with writer => newspaper" do
370
358
  Comment.includes(:post => :writer).where("posts.name like '%first%'").references(:posts).each do |comment|
371
359
  comment.post.writer.newspaper.name
372
360
  end
373
- #Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
374
- #Bullet::Detector::Association.should_not be_has_unused_preload_associations
361
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
362
+ Bullet::Detector::Association.should_not be_has_unused_preload_associations
375
363
 
376
364
  expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Writer, :newspaper)
377
365
  end
378
366
 
379
- # when we attempt to access category, there is an infinite overflow because load_target is hijacked leading to
380
- # a repeating loop of calls in this test
381
367
  it "should not raise a stack error from posts to category" do
382
368
  expect {
383
369
  Comment.includes({:post => :category}).each do |com|
@@ -389,15 +375,6 @@ if active_record4?
389
375
  end
390
376
 
391
377
  describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
392
- before(:each) do
393
- Bullet.clear
394
- Bullet.start_request
395
- end
396
-
397
- after(:each) do
398
- Bullet.end_request
399
- end
400
-
401
378
  context "students <=> teachers" do
402
379
  it "should detect non preload associations" do
403
380
  Student.all.each do |student|
@@ -438,15 +415,6 @@ if active_record4?
438
415
  end
439
416
 
440
417
  describe Bullet::Detector::Association, 'has_many :through' do
441
- before(:each) do
442
- Bullet.clear
443
- Bullet.start_request
444
- end
445
-
446
- after(:each) do
447
- Bullet.end_request
448
- end
449
-
450
418
  context "firm => clients" do
451
419
  it "should detect non preload associations" do
452
420
  Firm.all.each do |firm|
@@ -487,15 +455,6 @@ if active_record4?
487
455
  end
488
456
 
489
457
  describe Bullet::Detector::Association, "has_one" do
490
- before(:each) do
491
- Bullet.clear
492
- Bullet.start_request
493
- end
494
-
495
- after(:each) do
496
- Bullet.end_request
497
- end
498
-
499
458
  context "company => address" do
500
459
  it "should detect non preload association" do
501
460
  Company.all.each do |company|
@@ -536,15 +495,6 @@ if active_record4?
536
495
  end
537
496
 
538
497
  describe Bullet::Detector::Association, "call one association that in possible objects" do
539
- before(:each) do
540
- Bullet.clear
541
- Bullet.start_request
542
- end
543
-
544
- after(:each) do
545
- Bullet.end_request
546
- end
547
-
548
498
  it "should not detect preload association" do
549
499
  Post.all
550
500
  Post.first.comments.map(&:name)
@@ -556,15 +506,6 @@ if active_record4?
556
506
  end
557
507
 
558
508
  describe Bullet::Detector::Association, "STI" do
559
- before(:each) do
560
- Bullet.clear
561
- Bullet.start_request
562
- end
563
-
564
- after(:each) do
565
- Bullet.end_request
566
- end
567
-
568
509
  context "page => author" do
569
510
  it "should detect non preload associations" do
570
511
  Page.all.each do |page|
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- if active_record3? || active_record4?
3
+ if !mongoid? && active_record?
4
4
  describe Bullet::Detector::CounterCache do
5
5
  before(:each) do
6
6
  Bullet.start_request
@@ -2,15 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  if mongoid?
4
4
  describe Bullet::Detector::Association do
5
- before(:each) do
6
- Bullet.clear
7
- Bullet.start_request
8
- end
9
- after(:each) do
10
- Bullet.end_request
11
- Mongoid::IdentityMap.clear
12
- end
13
-
14
5
  context 'embeds_many' do
15
6
  context "posts => users" do
16
7
  it "should detect nothing" do
@@ -213,7 +204,6 @@ if mongoid?
213
204
  context "has_one" do
214
205
  context "company => address" do
215
206
  if Mongoid::VERSION !~ /\A3.0/
216
- # mongodid 3.0.x doesn't set relation properly, it will query company for each address which causes n+1 query.
217
207
  it "should detect non preload association" do
218
208
  Mongoid::Company.all.each do |company|
219
209
  company.address.name