bullet 4.0.0 → 4.13.1

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 (112) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -1
  4. data/.travis.yml +17 -6
  5. data/CHANGELOG.md +86 -0
  6. data/Gemfile +13 -12
  7. data/Gemfile.mongoid +14 -0
  8. data/Gemfile.mongoid-2.4 +19 -0
  9. data/Gemfile.mongoid-2.5 +19 -0
  10. data/Gemfile.mongoid-2.6 +19 -0
  11. data/Gemfile.mongoid-2.7 +19 -0
  12. data/Gemfile.mongoid-2.8 +19 -0
  13. data/Gemfile.mongoid-3.0 +19 -0
  14. data/Gemfile.mongoid-3.1 +19 -0
  15. data/Gemfile.mongoid-4.0 +19 -0
  16. data/Gemfile.rails-3.0 +19 -0
  17. data/Gemfile.rails-3.1 +19 -0
  18. data/Gemfile.rails-3.2 +19 -0
  19. data/Gemfile.rails-4.0 +19 -0
  20. data/Gemfile.rails-4.1 +19 -0
  21. data/{Hacking.textile → Hacking.md} +10 -5
  22. data/README.md +432 -0
  23. data/Rakefile +13 -6
  24. data/bullet.gemspec +6 -3
  25. data/lib/bullet/active_record3.rb +49 -11
  26. data/lib/bullet/active_record3x.rb +134 -0
  27. data/lib/bullet/{active_record31.rb → active_record4.rb} +45 -15
  28. data/lib/bullet/active_record41.rb +128 -0
  29. data/lib/bullet/dependency.rb +81 -0
  30. data/lib/bullet/detector/association.rb +24 -68
  31. data/lib/bullet/detector/base.rb +0 -6
  32. data/lib/bullet/detector/counter_cache.rb +59 -0
  33. data/lib/bullet/detector/n_plus_one_query.rb +56 -15
  34. data/lib/bullet/detector/unused_eager_loading.rb +84 -0
  35. data/lib/bullet/detector.rb +2 -2
  36. data/lib/bullet/ext/object.rb +10 -2
  37. data/lib/bullet/{mongoid.rb → mongoid2x.rb} +18 -18
  38. data/lib/bullet/mongoid3x.rb +56 -0
  39. data/lib/bullet/mongoid4x.rb +56 -0
  40. data/lib/bullet/notification/base.rb +22 -4
  41. data/lib/bullet/notification/n_plus_one_query.rb +1 -1
  42. data/lib/bullet/notification.rb +2 -0
  43. data/lib/bullet/rack.rb +51 -17
  44. data/lib/bullet/registry/base.rb +1 -1
  45. data/lib/bullet/registry/object.rb +4 -4
  46. data/lib/bullet/version.rb +1 -2
  47. data/lib/bullet.rb +119 -39
  48. data/perf/benchmark.rb +1 -4
  49. data/spec/bullet/detector/association_spec.rb +2 -70
  50. data/spec/bullet/detector/base_spec.rb +0 -6
  51. data/spec/bullet/detector/counter_cache_spec.rb +56 -0
  52. data/spec/bullet/detector/n_plus_one_query_spec.rb +78 -34
  53. data/spec/bullet/detector/unused_eager_loading_spec.rb +88 -0
  54. data/spec/bullet/ext/object_spec.rb +18 -7
  55. data/spec/bullet/ext/string_spec.rb +2 -2
  56. data/spec/bullet/notification/base_spec.rb +68 -15
  57. data/spec/bullet/notification/counter_cache_spec.rb +2 -2
  58. data/spec/bullet/notification/n_plus_one_query_spec.rb +4 -3
  59. data/spec/bullet/notification/unused_eager_loading_spec.rb +2 -2
  60. data/spec/bullet/notification_collector_spec.rb +4 -4
  61. data/spec/bullet/rack_spec.rb +40 -39
  62. data/spec/bullet/registry/association_spec.rb +3 -3
  63. data/spec/bullet/registry/base_spec.rb +6 -6
  64. data/spec/bullet/registry/object_spec.rb +4 -5
  65. data/spec/bullet_spec.rb +41 -0
  66. data/spec/integration/active_record3/association_spec.rb +662 -0
  67. data/spec/integration/active_record4/association_spec.rb +660 -0
  68. data/spec/integration/counter_cache_spec.rb +63 -0
  69. data/spec/integration/mongoid/association_spec.rb +190 -208
  70. data/spec/models/category.rb +1 -1
  71. data/spec/models/client.rb +1 -1
  72. data/spec/models/comment.rb +2 -2
  73. data/spec/models/document.rb +2 -2
  74. data/spec/models/firm.rb +1 -1
  75. data/spec/models/mongoid/address.rb +2 -0
  76. data/spec/models/mongoid/category.rb +2 -0
  77. data/spec/models/mongoid/comment.rb +2 -0
  78. data/spec/models/mongoid/company.rb +2 -0
  79. data/spec/models/mongoid/entry.rb +2 -0
  80. data/spec/models/mongoid/post.rb +4 -0
  81. data/spec/models/mongoid/user.rb +5 -0
  82. data/spec/models/newspaper.rb +1 -1
  83. data/spec/models/pet.rb +1 -1
  84. data/spec/models/post.rb +6 -13
  85. data/spec/spec_helper.rb +60 -25
  86. data/spec/support/bullet_ext.rb +1 -1
  87. data/spec/support/mongo_seed.rb +26 -2
  88. data/spec/support/sqlite_seed.rb +0 -6
  89. data/test.sh +15 -0
  90. metadata +77 -54
  91. data/.rvmrc +0 -2
  92. data/.rvmrc.example +0 -2
  93. data/Gemfile.lock +0 -132
  94. data/Gemfile.rails-2.3.14 +0 -16
  95. data/Gemfile.rails-2.3.14.lock +0 -65
  96. data/Gemfile.rails-3.0.12 +0 -17
  97. data/Gemfile.rails-3.0.12.lock +0 -116
  98. data/Gemfile.rails-3.1.4 +0 -18
  99. data/Gemfile.rails-3.1.4.lock +0 -134
  100. data/README.textile +0 -395
  101. data/README_for_rails2.textile +0 -400
  102. data/lib/bullet/action_controller2.rb +0 -49
  103. data/lib/bullet/active_record2.rb +0 -121
  104. data/lib/bullet/detector/counter.rb +0 -48
  105. data/lib/bullet/detector/unused_eager_association.rb +0 -42
  106. data/spec/bullet/detector/counter_spec.rb +0 -64
  107. data/spec/bullet/detector/unused_eager_association_spec.rb +0 -62
  108. data/spec/integration/association_spec.rb +0 -593
  109. data/spec/integration/counter_spec.rb +0 -39
  110. data/spec/integration/rails2/association_spec.rb +0 -593
  111. data/spec/integration/rails2/counter_spec.rb +0 -39
  112. data/test.result +0 -2293
@@ -0,0 +1,662 @@
1
+ require 'spec_helper'
2
+
3
+ if !mongoid? && active_record3?
4
+ describe Bullet::Detector::Association, 'has_many' do
5
+ context "post => comments" do
6
+ it "should detect non preload post => comments" do
7
+ Post.all.each do |post|
8
+ post.comments.map(&:name)
9
+ end
10
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
11
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
12
+
13
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
14
+ end
15
+
16
+ it "should detect preload with post => comments" do
17
+ Post.includes(:comments).each do |post|
18
+ post.comments.map(&:name)
19
+ end
20
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
21
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
22
+
23
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
24
+ end
25
+
26
+ it "should detect unused preload post => comments" do
27
+ Post.includes(:comments).map(&:name)
28
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
29
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
30
+
31
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
32
+ end
33
+
34
+ it "should not detect unused preload post => comments" do
35
+ Post.all.map(&:name)
36
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
37
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
38
+
39
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
40
+ end
41
+
42
+ it "should not detect non preload comment => post with inverse_of" do
43
+ Post.includes(:comments).each do |post|
44
+ post.comments.each do |comment|
45
+ comment.name
46
+ comment.post.name
47
+ end
48
+ end
49
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
50
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
51
+
52
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
53
+ end
54
+
55
+ it "should detect non preload post => comments with empty?" do
56
+ Post.all.each do |post|
57
+ post.comments.empty?
58
+ end
59
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
60
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
61
+
62
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
63
+ end
64
+
65
+ it "should detect non preload post => comments with include?" do
66
+ comment = Comment.last
67
+ Post.all.each do |post|
68
+ post.comments.include?(comment)
69
+ end
70
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
71
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
72
+
73
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
74
+ end
75
+ end
76
+
77
+ context "category => posts => comments" do
78
+ it "should detect non preload category => posts => comments" do
79
+ Category.all.each do |category|
80
+ category.posts.each do |post|
81
+ post.comments.map(&:name)
82
+ end
83
+ end
84
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
85
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
86
+
87
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Category, :posts)
88
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
89
+ end
90
+
91
+ it "should detect preload category => posts, but no post => comments" do
92
+ Category.includes(:posts).each do |category|
93
+ category.posts.each do |post|
94
+ post.comments.map(&:name)
95
+ end
96
+ end
97
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
98
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
99
+
100
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Category, :posts)
101
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
102
+ end
103
+
104
+ it "should detect preload with category => posts => comments" do
105
+ Category.includes({:posts => :comments}).each do |category|
106
+ category.posts.each do |post|
107
+ post.comments.map(&:name)
108
+ end
109
+ end
110
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
111
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
112
+
113
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
114
+ end
115
+
116
+ it "should detect preload with category => posts => comments with posts.id > 0" do
117
+ Category.includes({:posts => :comments}).where('posts.id > 0').each do |category|
118
+ category.posts.each do |post|
119
+ post.comments.map(&:name)
120
+ end
121
+ end
122
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
123
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
124
+
125
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
126
+ end
127
+
128
+ it "should detect unused preload with category => posts => comments" do
129
+ Category.includes({:posts => :comments}).map(&:name)
130
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
131
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
132
+
133
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
134
+ end
135
+
136
+ it "should detect unused preload with post => commnets, no category => posts" do
137
+ Category.includes({:posts => :comments}).each do |category|
138
+ category.posts.map(&:name)
139
+ end
140
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
141
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
142
+
143
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
144
+ end
145
+ end
146
+
147
+ context "category => posts, category => entries" do
148
+ it "should detect non preload with category => [posts, entries]" do
149
+ Category.all.each do |category|
150
+ category.posts.map(&:name)
151
+ category.entries.map(&:name)
152
+ end
153
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
154
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
155
+
156
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Category, :posts)
157
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Category, :entries)
158
+ end
159
+
160
+ it "should detect preload with category => posts, but not with category => entries" do
161
+ Category.includes(:posts).each do |category|
162
+ category.posts.map(&:name)
163
+ category.entries.map(&:name)
164
+ end
165
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
166
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
167
+
168
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Category, :posts)
169
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Category, :entries)
170
+ end
171
+
172
+ it "should detect preload with category => [posts, entries]" do
173
+ Category.includes([:posts, :entries]).each do |category|
174
+ category.posts.map(&:name)
175
+ category.entries.map(&:name)
176
+ end
177
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
178
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
179
+
180
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
181
+ end
182
+
183
+ it "should detect unused preload with category => [posts, entries]" do
184
+ Category.includes([:posts, :entries]).map(&:name)
185
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
186
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Category, :posts)
187
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Category, :entries)
188
+
189
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
190
+ end
191
+
192
+ it "should detect unused preload with category => entries, but not with category => posts" do
193
+ Category.includes([:posts, :entries]).each do |category|
194
+ category.posts.map(&:name)
195
+ end
196
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
197
+ expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Category, :posts)
198
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Category, :entries)
199
+
200
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
201
+ end
202
+ end
203
+
204
+ context "post => comment" do
205
+ it "should detect unused preload with post => comments" do
206
+ Post.includes(:comments).each do |post|
207
+ post.comments.first.name
208
+ end
209
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
210
+ expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :comments)
211
+
212
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
213
+ end
214
+
215
+ it "should detect preload with post => commnets" do
216
+ Post.first.comments.map(&:name)
217
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
218
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
219
+
220
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
221
+ end
222
+ end
223
+
224
+ context "category => posts => writer" do
225
+ it "should not detect unused preload associations" do
226
+ category = Category.includes({:posts => :writer}).order("id DESC").find_by_name('first')
227
+ category.posts.map do |post|
228
+ post.name
229
+ post.writer.name
230
+ end
231
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
232
+ expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Category, :posts)
233
+ expect(Bullet::Detector::Association).not_to be_unused_preload_associations_for(Post, :writer)
234
+
235
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
236
+ end
237
+ end
238
+
239
+ context "scope for_category_name" do
240
+ it "should detect preload with post => category" do
241
+ Post.in_category_name('first').each do |post|
242
+ post.category.name
243
+ end
244
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
245
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
246
+
247
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
248
+ end
249
+
250
+ it "should not be unused preload post => category" do
251
+ Post.in_category_name('first').all.map(&:name)
252
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
253
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
254
+
255
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
256
+ end
257
+ end
258
+
259
+ context "scope preload_comments" do
260
+ it "should detect preload post => comments with scope" do
261
+ Post.preload_comments.each do |post|
262
+ post.comments.map(&:name)
263
+ end
264
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
265
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
266
+
267
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
268
+ end
269
+
270
+ it "should detect unused preload with scope" do
271
+ Post.preload_comments.map(&:name)
272
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
273
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
274
+
275
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
276
+ end
277
+ end
278
+ end
279
+
280
+ describe Bullet::Detector::Association, 'belongs_to' do
281
+ context "comment => post" do
282
+ it "should detect non preload with comment => post" do
283
+ Comment.all.each do |comment|
284
+ comment.post.name
285
+ end
286
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
287
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
288
+
289
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Comment, :post)
290
+ end
291
+
292
+ it "should detect preload with one comment => post" do
293
+ Comment.first.post.name
294
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
295
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
296
+
297
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
298
+ end
299
+
300
+ it "should dtect preload with comment => post" do
301
+ Comment.includes(:post).each do |comment|
302
+ comment.post.name
303
+ end
304
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
305
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
306
+
307
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
308
+ end
309
+
310
+ it "should not detect preload with comment => post" do
311
+ Comment.all.map(&:name)
312
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
313
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
314
+
315
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
316
+ end
317
+
318
+ it "should detect unused preload with comments => post" do
319
+ Comment.includes(:post).map(&:name)
320
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
321
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Comment, :post)
322
+
323
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
324
+ end
325
+ end
326
+
327
+ context "comment => post => category" do
328
+ it "should detect non preload association with comment => post" do
329
+ Comment.all.each do |comment|
330
+ comment.post.category.name
331
+ end
332
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
333
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
334
+
335
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Comment, :post)
336
+ end
337
+
338
+ it "should detect non preload association with post => category" do
339
+ Comment.includes(:post).each do |comment|
340
+ comment.post.category.name
341
+ end
342
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
343
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
344
+
345
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :category)
346
+ end
347
+
348
+ it "should not detect unpreload association" do
349
+ Comment.includes(:post => :category).each do |comment|
350
+ comment.post.category.name
351
+ end
352
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
353
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
354
+
355
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
356
+ end
357
+ end
358
+
359
+ context "comment => author, post => writer" do
360
+ it "should detect non preloaded writer" do
361
+ Comment.includes([:author, :post]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
362
+ comment.post.writer.name
363
+ end
364
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
365
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
366
+
367
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :writer)
368
+ end
369
+
370
+ it "should detect unused preload with comment => author" do
371
+ Comment.includes([:author, {:post => :writer}]).where(["base_users.id = ?", BaseUser.first]).each do |comment|
372
+ comment.post.writer.name
373
+ end
374
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
375
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
376
+
377
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
378
+ end
379
+
380
+ it "should detect non preloading with writer => newspaper" do
381
+ Comment.all(:include => {:post => :writer}, :conditions => "posts.name like '%first%'").each do |comment|
382
+ comment.post.writer.newspaper.name
383
+ end
384
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
385
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
386
+
387
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Writer, :newspaper)
388
+ end
389
+
390
+ it "should not raise a stack error from posts to category" do
391
+ expect {
392
+ Comment.includes({:post => :category}).each do |com|
393
+ com.post.category
394
+ end
395
+ }.not_to raise_error
396
+ end
397
+ end
398
+ end
399
+
400
+ describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
401
+ context "students <=> teachers" do
402
+ it "should detect non preload associations" do
403
+ Student.all.each do |student|
404
+ student.teachers.map(&:name)
405
+ end
406
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
407
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
408
+
409
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
410
+ end
411
+
412
+ it "should detect preload associations" do
413
+ Student.includes(:teachers).each do |student|
414
+ student.teachers.map(&:name)
415
+ end
416
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
417
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
418
+
419
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
420
+ end
421
+
422
+ it "should detect unused preload associations" do
423
+ Student.includes(:teachers).map(&:name)
424
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
425
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Student, :teachers)
426
+
427
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
428
+ end
429
+
430
+ it "should detect no unused preload associations" do
431
+ Student.all.map(&:name)
432
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
433
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
434
+
435
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
436
+ end
437
+ end
438
+ end
439
+
440
+ describe Bullet::Detector::Association, 'has_many :through' do
441
+ context "firm => clients" do
442
+ it "should detect non preload associations" do
443
+ Firm.all.each do |firm|
444
+ firm.clients.map(&:name)
445
+ end
446
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
447
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
448
+
449
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Firm, :clients)
450
+ end
451
+
452
+ it "should detect preload associations" do
453
+ Firm.includes(:clients).each do |firm|
454
+ firm.clients.map(&:name)
455
+ end
456
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
457
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
458
+
459
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
460
+ end
461
+
462
+ it "should not detect preload associations" do
463
+ Firm.all.map(&:name)
464
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
465
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
466
+
467
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
468
+ end
469
+
470
+ it "should detect unused preload associations" do
471
+ Firm.includes(:clients).map(&:name)
472
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
473
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Firm, :clients)
474
+
475
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
476
+ end
477
+ end
478
+ end
479
+
480
+ describe Bullet::Detector::Association, "has_one" do
481
+ context "company => address" do
482
+ it "should detect non preload association" do
483
+ Company.all.each do |company|
484
+ company.address.name
485
+ end
486
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
487
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
488
+
489
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Company, :address)
490
+ end
491
+
492
+ it "should detect preload association" do
493
+ Company.includes(:address).each do |company|
494
+ company.address.name
495
+ end
496
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
497
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
498
+
499
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
500
+ end
501
+
502
+ it "should not detect preload association" do
503
+ Company.all.map(&:name)
504
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
505
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
506
+
507
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
508
+ end
509
+
510
+ it "should detect unused preload association" do
511
+ Company.includes(:address).map(&:name)
512
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
513
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Company, :address)
514
+
515
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
516
+ end
517
+ end
518
+ end
519
+
520
+ describe Bullet::Detector::Association, "call one association that in possible objects" do
521
+ it "should not detect preload association" do
522
+ Post.all
523
+ Post.first.comments.map(&:name)
524
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
525
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
526
+
527
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
528
+ end
529
+ end
530
+
531
+ describe Bullet::Detector::Association, "STI" do
532
+ context "page => author" do
533
+ it "should detect non preload associations" do
534
+ Page.all.each do |page|
535
+ page.author.name
536
+ end
537
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
538
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
539
+
540
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Page, :author)
541
+ end
542
+
543
+ it "should detect preload associations" do
544
+ Page.includes(:author).each do |page|
545
+ page.author.name
546
+ end
547
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
548
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
549
+
550
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
551
+ end
552
+
553
+ it "should detect unused preload associations" do
554
+ Page.includes(:author).map(&:name)
555
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
556
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Page, :author)
557
+
558
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
559
+ end
560
+
561
+ it "should not detect preload associations" do
562
+ Page.all.map(&:name)
563
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
564
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
565
+
566
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
567
+ end
568
+ end
569
+
570
+ context "disable n plus one query" do
571
+ before { Bullet.n_plus_one_query_enable = false }
572
+ after { Bullet.n_plus_one_query_enable = true }
573
+
574
+ it "should not detect n plus one query" do
575
+ Post.all.each do |post|
576
+ post.comments.map(&:name)
577
+ end
578
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
579
+
580
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
581
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
582
+ end
583
+
584
+ it "should still detect unused eager loading" do
585
+ Post.includes(:comments).map(&:name)
586
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
587
+
588
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
589
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
590
+ end
591
+ end
592
+
593
+ context "disable unused eager loading" do
594
+ before { Bullet.unused_eager_loading_enable = false }
595
+ after { Bullet.unused_eager_loading_enable = true }
596
+
597
+ it "should not detect unused eager loading" do
598
+ Post.includes(:comments).map(&:name)
599
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
600
+
601
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
602
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
603
+ end
604
+
605
+ it "should still detect n plus one query" do
606
+ Post.all.each do |post|
607
+ post.comments.map(&:name)
608
+ end
609
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
610
+
611
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
612
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
613
+ end
614
+ end
615
+
616
+ context "whitelist n plus one query" do
617
+ before { Bullet.add_whitelist :type => :n_plus_one_query, :class_name => "Post", :association => :comments }
618
+ after { Bullet.reset_whitelist }
619
+
620
+ it "should not detect n plus one query" do
621
+ Post.all.each do |post|
622
+ post.comments.map(&:name)
623
+ end
624
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
625
+
626
+ expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(Post, :comments)
627
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
628
+ end
629
+
630
+ it "should still detect unused eager loading" do
631
+ Post.includes(:comments).map(&:name)
632
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
633
+
634
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
635
+ expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
636
+ end
637
+ end
638
+
639
+ context "whitelist unused eager loading" do
640
+ before { Bullet.add_whitelist :type => :unused_eager_loading, :class_name => "Post", :association => :comments }
641
+ after { Bullet.reset_whitelist }
642
+
643
+ it "should not detect unused eager loading" do
644
+ Post.includes(:comments).map(&:name)
645
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
646
+
647
+ expect(Bullet::Detector::Association).to be_completely_preloading_associations
648
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
649
+ end
650
+
651
+ it "should still detect n plus one query" do
652
+ Post.all.each do |post|
653
+ post.comments.map(&:name)
654
+ end
655
+ Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
656
+
657
+ expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Post, :comments)
658
+ expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
659
+ end
660
+ end
661
+ end
662
+ end