bullet 4.9.0 → 4.10.0

Sign up to get free protection for your applications and to get access to all the features.
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