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