bullet 4.11.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/Gemfile.mongoid-4.0 +1 -1
- data/Gemfile.rails-3.2 +1 -1
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/README.md +52 -46
- data/bullet.gemspec +2 -2
- data/lib/bullet/active_record3.rb +1 -1
- data/lib/bullet/active_record3x.rb +1 -1
- data/lib/bullet/active_record4.rb +1 -11
- data/lib/bullet/active_record41.rb +1 -0
- data/lib/bullet/detector/association.rb +13 -7
- data/lib/bullet/detector/counter_cache.rb +11 -11
- data/lib/bullet/detector/n_plus_one_query.rb +28 -18
- data/lib/bullet/detector/unused_eager_loading.rb +16 -16
- data/lib/bullet/ext/object.rb +8 -4
- data/lib/bullet/notification/base.rb +5 -5
- data/lib/bullet/rack.rb +1 -1
- data/lib/bullet/registry/object.rb +4 -4
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +5 -2
- data/spec/bullet/detector/association_spec.rb +2 -2
- data/spec/bullet/detector/counter_cache_spec.rb +8 -8
- data/spec/bullet/detector/n_plus_one_query_spec.rb +27 -27
- data/spec/bullet/detector/unused_eager_loading_spec.rb +15 -15
- data/spec/bullet/ext/object_spec.rb +17 -3
- data/spec/bullet/notification/base_spec.rb +37 -0
- data/spec/bullet/registry/object_spec.rb +4 -4
- data/spec/bullet_spec.rb +2 -2
- data/spec/integration/active_record3/association_spec.rb +2 -2
- data/spec/integration/active_record4/association_spec.rb +1 -1
- data/spec/models/category.rb +1 -1
- data/spec/models/post.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/support/bullet_ext.rb +1 -1
- metadata +6 -6
|
@@ -10,27 +10,27 @@ module Bullet
|
|
|
10
10
|
return unless Bullet.start?
|
|
11
11
|
return unless Bullet.unused_eager_loading_enable?
|
|
12
12
|
|
|
13
|
-
object_associations.each do |
|
|
14
|
-
object_association_diff = diff_object_associations
|
|
13
|
+
object_associations.each do |bullet_key, associations|
|
|
14
|
+
object_association_diff = diff_object_associations bullet_key, associations
|
|
15
15
|
next if object_association_diff.empty?
|
|
16
16
|
|
|
17
|
-
Bullet.debug("detect unused preload", "object: #{
|
|
18
|
-
create_notification
|
|
17
|
+
Bullet.debug("detect unused preload", "object: #{bullet_key}, associations: #{object_association_diff}")
|
|
18
|
+
create_notification bullet_key.bullet_class_name, object_association_diff
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def add_eager_loadings(objects, associations)
|
|
23
23
|
return unless Bullet.start?
|
|
24
24
|
return unless Bullet.unused_eager_loading_enable?
|
|
25
|
-
return if objects.map(&:
|
|
25
|
+
return if objects.map(&:primary_key_value).compact.empty?
|
|
26
26
|
|
|
27
|
-
Bullet.debug("Detector::UnusedEagerLoading#add_eager_loadings", "objects: #{objects.map(&:
|
|
28
|
-
|
|
27
|
+
Bullet.debug("Detector::UnusedEagerLoading#add_eager_loadings", "objects: #{objects.map(&:bullet_key).join(', ')}, associations: #{associations}")
|
|
28
|
+
bullet_keys = objects.map(&:bullet_key)
|
|
29
29
|
|
|
30
30
|
to_add = nil
|
|
31
31
|
to_merge, to_delete = [], []
|
|
32
32
|
eager_loadings.each do |k, v|
|
|
33
|
-
key_objects_overlap = k &
|
|
33
|
+
key_objects_overlap = k & bullet_keys
|
|
34
34
|
|
|
35
35
|
next if key_objects_overlap.empty?
|
|
36
36
|
|
|
@@ -40,10 +40,10 @@ module Bullet
|
|
|
40
40
|
else
|
|
41
41
|
to_merge << [key_objects_overlap, ( eager_loadings[k].dup << associations )]
|
|
42
42
|
|
|
43
|
-
keys_without_objects = k -
|
|
43
|
+
keys_without_objects = k - bullet_keys
|
|
44
44
|
to_merge << [keys_without_objects, eager_loadings[k]]
|
|
45
45
|
to_delete << k
|
|
46
|
-
|
|
46
|
+
bullet_keys = bullet_keys - k
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -51,7 +51,7 @@ module Bullet
|
|
|
51
51
|
to_merge.each { |k,val| eager_loadings.merge k, val }
|
|
52
52
|
to_delete.each { |k| eager_loadings.delete k }
|
|
53
53
|
|
|
54
|
-
eager_loadings.add
|
|
54
|
+
eager_loadings.add bullet_keys, associations unless bullet_keys.empty?
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
private
|
|
@@ -64,18 +64,18 @@ module Bullet
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
def call_associations(
|
|
67
|
+
def call_associations(bullet_key, associations)
|
|
68
68
|
all = Set.new
|
|
69
|
-
eager_loadings.similarly_associated(
|
|
70
|
-
coa = call_object_associations[
|
|
69
|
+
eager_loadings.similarly_associated(bullet_key, associations).each do |related_bullet_key|
|
|
70
|
+
coa = call_object_associations[related_bullet_key]
|
|
71
71
|
next if coa.nil?
|
|
72
72
|
all.merge coa
|
|
73
73
|
end
|
|
74
74
|
all.to_a
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def diff_object_associations(
|
|
78
|
-
potential_associations = associations - call_associations(
|
|
77
|
+
def diff_object_associations(bullet_key, associations)
|
|
78
|
+
potential_associations = associations - call_associations(bullet_key, associations)
|
|
79
79
|
potential_associations.reject { |a| a.is_a?(Hash) }
|
|
80
80
|
end
|
|
81
81
|
end
|
data/lib/bullet/ext/object.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
class Object
|
|
2
|
-
def
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
def bullet_key
|
|
3
|
+
[self.class, self.primary_key_value].join(':')
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def primary_key_value
|
|
7
|
+
if self.class.respond_to?(:primary_key) && self.class.primary_key
|
|
8
|
+
self.send self.class.primary_key
|
|
5
9
|
else
|
|
6
|
-
|
|
10
|
+
self.id
|
|
7
11
|
end
|
|
8
12
|
end
|
|
9
13
|
end
|
|
@@ -19,9 +19,9 @@ module Bullet
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def whoami
|
|
22
|
-
user
|
|
23
|
-
if user
|
|
24
|
-
"user: #{user
|
|
22
|
+
@user ||= ENV['USER'].presence || (`whoami`.chomp rescue "")
|
|
23
|
+
if @user.present?
|
|
24
|
+
"user: #{@user}"
|
|
25
25
|
else
|
|
26
26
|
""
|
|
27
27
|
end
|
|
@@ -36,7 +36,7 @@ module Bullet
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def full_notice
|
|
39
|
-
[whoami, url, title, body_with_caller].compact.join("\n")
|
|
39
|
+
[whoami.presence, url, title, body_with_caller].compact.join("\n")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def notify_inline
|
|
@@ -48,7 +48,7 @@ module Bullet
|
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def short_notice
|
|
51
|
-
[whoami, url, title, body].compact.join("\n")
|
|
51
|
+
[whoami.presence, url, title, body].compact.join("\n")
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def notification_data
|
data/lib/bullet/rack.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module Bullet
|
|
2
2
|
module Registry
|
|
3
3
|
class Object < Base
|
|
4
|
-
def add(
|
|
5
|
-
super(
|
|
4
|
+
def add(bullet_key)
|
|
5
|
+
super(bullet_key.bullet_class_name, bullet_key)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def include?(
|
|
9
|
-
super(
|
|
8
|
+
def include?(bullet_key)
|
|
9
|
+
super(bullet_key.bullet_class_name, bullet_key)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
|
@@ -96,7 +96,7 @@ module Bullet
|
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
def debug(title, message)
|
|
99
|
-
puts "[Bullet][#{title}] #{message}" if ENV['
|
|
99
|
+
puts "[Bullet][#{title}] #{message}" if ENV['BULLET_DEBUG'] == 'true'
|
|
100
100
|
end
|
|
101
101
|
|
|
102
102
|
def start_request
|
|
@@ -107,6 +107,7 @@ module Bullet
|
|
|
107
107
|
Thread.current[:bullet_call_object_associations] = Bullet::Registry::Base.new
|
|
108
108
|
Thread.current[:bullet_possible_objects] = Bullet::Registry::Object.new
|
|
109
109
|
Thread.current[:bullet_impossible_objects] = Bullet::Registry::Object.new
|
|
110
|
+
Thread.current[:bullet_inversed_objects] = Bullet::Registry::Base.new
|
|
110
111
|
Thread.current[:bullet_eager_loadings] = Bullet::Registry::Association.new
|
|
111
112
|
|
|
112
113
|
Thread.current[:bullet_counter_possible_objects] ||= Bullet::Registry::Object.new
|
|
@@ -118,9 +119,10 @@ module Bullet
|
|
|
118
119
|
Thread.current[:bullet_notification_collector] = nil
|
|
119
120
|
|
|
120
121
|
Thread.current[:bullet_object_associations] = nil
|
|
122
|
+
Thread.current[:bullet_call_object_associations] = nil
|
|
121
123
|
Thread.current[:bullet_possible_objects] = nil
|
|
122
124
|
Thread.current[:bullet_impossible_objects] = nil
|
|
123
|
-
Thread.current[:
|
|
125
|
+
Thread.current[:bullet_inversed_objects] = nil
|
|
124
126
|
Thread.current[:bullet_eager_loadings] = nil
|
|
125
127
|
|
|
126
128
|
Thread.current[:bullet_counter_possible_objects] = nil
|
|
@@ -136,6 +138,7 @@ module Bullet
|
|
|
136
138
|
end
|
|
137
139
|
|
|
138
140
|
def notification?
|
|
141
|
+
return unless start?
|
|
139
142
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
140
143
|
notification_collector.notifications_present?
|
|
141
144
|
end
|
|
@@ -11,14 +11,14 @@ module Bullet
|
|
|
11
11
|
context ".add_object_association" do
|
|
12
12
|
it "should add object, associations pair" do
|
|
13
13
|
Association.add_object_associations(@post1, :associations)
|
|
14
|
-
expect(Association.send(:object_associations)).to be_include(@post1.
|
|
14
|
+
expect(Association.send(:object_associations)).to be_include(@post1.bullet_key, :associations)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
context ".add_call_object_associations" do
|
|
19
19
|
it "should add call object, associations pair" do
|
|
20
20
|
Association.add_call_object_associations(@post1, :associations)
|
|
21
|
-
expect(Association.send(:call_object_associations)).to be_include(@post1.
|
|
21
|
+
expect(Association.send(:call_object_associations)).to be_include(@post1.bullet_key, :associations)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -10,13 +10,13 @@ module Bullet
|
|
|
10
10
|
|
|
11
11
|
context ".add_counter_cache" do
|
|
12
12
|
it "should create notification if conditions met" do
|
|
13
|
-
expect(CounterCache).to receive(:conditions_met?).with(@post1.
|
|
13
|
+
expect(CounterCache).to receive(:conditions_met?).with(@post1.bullet_key, [:comments]).and_return(true)
|
|
14
14
|
expect(CounterCache).to receive(:create_notification).with("Post", [:comments])
|
|
15
15
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "should not create notification if conditions not met" do
|
|
19
|
-
expect(CounterCache).to receive(:conditions_met?).with(@post1.
|
|
19
|
+
expect(CounterCache).to receive(:conditions_met?).with(@post1.bullet_key, [:comments]).and_return(false)
|
|
20
20
|
expect(CounterCache).to receive(:create_notification).never
|
|
21
21
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
22
22
|
end
|
|
@@ -25,30 +25,30 @@ module Bullet
|
|
|
25
25
|
context ".add_possible_objects" do
|
|
26
26
|
it "should add possible objects" do
|
|
27
27
|
CounterCache.add_possible_objects([@post1, @post2])
|
|
28
|
-
expect(CounterCache.send(:possible_objects)).to be_include(@post1.
|
|
29
|
-
expect(CounterCache.send(:possible_objects)).to be_include(@post2.
|
|
28
|
+
expect(CounterCache.send(:possible_objects)).to be_include(@post1.bullet_key)
|
|
29
|
+
expect(CounterCache.send(:possible_objects)).to be_include(@post2.bullet_key)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it "should add impossible object" do
|
|
33
33
|
CounterCache.add_impossible_object(@post1)
|
|
34
|
-
expect(CounterCache.send(:impossible_objects)).to be_include(@post1.
|
|
34
|
+
expect(CounterCache.send(:impossible_objects)).to be_include(@post1.bullet_key)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
context ".conditions_met?" do
|
|
39
39
|
it "should be true when object is possible, not impossible" do
|
|
40
40
|
CounterCache.add_possible_objects(@post1)
|
|
41
|
-
expect(CounterCache.send(:conditions_met?, @post1.
|
|
41
|
+
expect(CounterCache.send(:conditions_met?, @post1.bullet_key, :associations)).to eq true
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
it "should be false when object is not possible" do
|
|
45
|
-
expect(CounterCache.send(:conditions_met?, @post1.
|
|
45
|
+
expect(CounterCache.send(:conditions_met?, @post1.bullet_key, :associations)).to eq false
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
it "should be true when object is possible, and impossible" do
|
|
49
49
|
CounterCache.add_possible_objects(@post1)
|
|
50
50
|
CounterCache.add_impossible_object(@post1)
|
|
51
|
-
expect(CounterCache.send(:conditions_met?, @post1.
|
|
51
|
+
expect(CounterCache.send(:conditions_met?, @post1.bullet_key, :associations)).to eq false
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
@@ -18,69 +18,69 @@ module Bullet
|
|
|
18
18
|
context ".possible?" do
|
|
19
19
|
it "should be true if possible_objects contain" do
|
|
20
20
|
NPlusOneQuery.add_possible_objects(@post)
|
|
21
|
-
expect(NPlusOneQuery.send(:possible?, @post.
|
|
21
|
+
expect(NPlusOneQuery.send(:possible?, @post.bullet_key)).to eq true
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
context ".impossible?" do
|
|
26
26
|
it "should be true if impossible_objects contain" do
|
|
27
27
|
NPlusOneQuery.add_impossible_object(@post)
|
|
28
|
-
expect(NPlusOneQuery.send(:impossible?, @post.
|
|
28
|
+
expect(NPlusOneQuery.send(:impossible?, @post.bullet_key)).to eq true
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
context ".association?" do
|
|
33
33
|
it "should be true if object, associations pair is already existed" do
|
|
34
34
|
NPlusOneQuery.add_object_associations(@post, :association)
|
|
35
|
-
expect(NPlusOneQuery.send(:association?, @post.
|
|
35
|
+
expect(NPlusOneQuery.send(:association?, @post.bullet_key, :association)).to eq true
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
it "should be false if object, association pair is not existed" do
|
|
39
39
|
NPlusOneQuery.add_object_associations(@post, :association1)
|
|
40
|
-
expect(NPlusOneQuery.send(:association?, @post.
|
|
40
|
+
expect(NPlusOneQuery.send(:association?, @post.bullet_key, :associatio2)).to eq false
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
context ".conditions_met?" do
|
|
45
45
|
it "should be true if object is possible, not impossible and object, associations pair is not already existed" do
|
|
46
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post.
|
|
47
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post.
|
|
48
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post.
|
|
49
|
-
expect(NPlusOneQuery.send(:conditions_met?, @post.
|
|
46
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post.bullet_key).and_return(true)
|
|
47
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post.bullet_key).and_return(false)
|
|
48
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post.bullet_key, :associations).and_return(false)
|
|
49
|
+
expect(NPlusOneQuery.send(:conditions_met?, @post.bullet_key, :associations)).to eq true
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it "should be false if object is not possible, not impossible and object, associations pair is not already existed" do
|
|
53
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post.
|
|
54
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post.
|
|
55
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post.
|
|
56
|
-
expect(NPlusOneQuery.send(:conditions_met?, @post.
|
|
53
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post.bullet_key).and_return(false)
|
|
54
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post.bullet_key).and_return(false)
|
|
55
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post.bullet_key, :associations).and_return(false)
|
|
56
|
+
expect(NPlusOneQuery.send(:conditions_met?, @post.bullet_key, :associations)).to eq false
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it "should be false if object is possible, but impossible and object, associations pair is not already existed" do
|
|
60
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post.
|
|
61
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post.
|
|
62
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post.
|
|
63
|
-
expect(NPlusOneQuery.send(:conditions_met?, @post.
|
|
60
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post.bullet_key).and_return(true)
|
|
61
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post.bullet_key).and_return(true)
|
|
62
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post.bullet_key, :associations).and_return(false)
|
|
63
|
+
expect(NPlusOneQuery.send(:conditions_met?, @post.bullet_key, :associations)).to eq false
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it "should be false if object is possible, not impossible and object, associations pair is already existed" do
|
|
67
|
-
allow(NPlusOneQuery).to receive(:possible?).with(@post.
|
|
68
|
-
allow(NPlusOneQuery).to receive(:impossible?).with(@post.
|
|
69
|
-
allow(NPlusOneQuery).to receive(:association?).with(@post.
|
|
70
|
-
expect(NPlusOneQuery.send(:conditions_met?, @post.
|
|
67
|
+
allow(NPlusOneQuery).to receive(:possible?).with(@post.bullet_key).and_return(true)
|
|
68
|
+
allow(NPlusOneQuery).to receive(:impossible?).with(@post.bullet_key).and_return(false)
|
|
69
|
+
allow(NPlusOneQuery).to receive(:association?).with(@post.bullet_key, :associations).and_return(true)
|
|
70
|
+
expect(NPlusOneQuery.send(:conditions_met?, @post.bullet_key, :associations)).to eq false
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
context ".call_association" do
|
|
75
75
|
it "should create notification if conditions met" do
|
|
76
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.
|
|
76
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_key, :association).and_return(true)
|
|
77
77
|
expect(NPlusOneQuery).to receive(:caller_in_project).and_return(["caller"])
|
|
78
78
|
expect(NPlusOneQuery).to receive(:create_notification).with(["caller"], "Post", :association)
|
|
79
79
|
NPlusOneQuery.call_association(@post, :association)
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
it "should not create notification if conditions not met" do
|
|
83
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.
|
|
83
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_key, :association).and_return(false)
|
|
84
84
|
expect(NPlusOneQuery).not_to receive(:caller_in_project!)
|
|
85
85
|
expect(NPlusOneQuery).not_to receive(:create_notification).with("Post", :association)
|
|
86
86
|
NPlusOneQuery.call_association(@post, :association)
|
|
@@ -93,7 +93,7 @@ module Bullet
|
|
|
93
93
|
not_in_project = '/def/def.rb'
|
|
94
94
|
|
|
95
95
|
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, not_in_project])
|
|
96
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.
|
|
96
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_key, :association).and_return(true)
|
|
97
97
|
expect(NPlusOneQuery).to receive(:create_notification).with([in_project], "Post", :association)
|
|
98
98
|
NPlusOneQuery.call_association(@post, :association)
|
|
99
99
|
end
|
|
@@ -108,7 +108,7 @@ module Bullet
|
|
|
108
108
|
excluded_gem = '/ghi/ghi.rb'
|
|
109
109
|
|
|
110
110
|
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, included_gem, excluded_gem])
|
|
111
|
-
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.
|
|
111
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_key, :association).and_return(true)
|
|
112
112
|
expect(NPlusOneQuery).to receive(:create_notification).with([in_project, included_gem], "Post", :association)
|
|
113
113
|
NPlusOneQuery.call_association(@post, :association)
|
|
114
114
|
end
|
|
@@ -118,8 +118,8 @@ module Bullet
|
|
|
118
118
|
context ".add_possible_objects" do
|
|
119
119
|
it "should add possible objects" do
|
|
120
120
|
NPlusOneQuery.add_possible_objects([@post, @post2])
|
|
121
|
-
expect(NPlusOneQuery.send(:possible_objects)).to be_include(@post.
|
|
122
|
-
expect(NPlusOneQuery.send(:possible_objects)).to be_include(@post2.
|
|
121
|
+
expect(NPlusOneQuery.send(:possible_objects)).to be_include(@post.bullet_key)
|
|
122
|
+
expect(NPlusOneQuery.send(:possible_objects)).to be_include(@post2.bullet_key)
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
it "should not raise error if object is nil" do
|
|
@@ -130,7 +130,7 @@ module Bullet
|
|
|
130
130
|
context ".add_impossible_object" do
|
|
131
131
|
it "should add impossible object" do
|
|
132
132
|
NPlusOneQuery.add_impossible_object(@post)
|
|
133
|
-
expect(NPlusOneQuery.send(:impossible_objects)).to be_include(@post.
|
|
133
|
+
expect(NPlusOneQuery.send(:impossible_objects)).to be_include(@post.bullet_key)
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
end
|
|
@@ -10,30 +10,30 @@ module Bullet
|
|
|
10
10
|
|
|
11
11
|
context ".call_associations" do
|
|
12
12
|
it "should get empty array if eager_loadings" do
|
|
13
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.
|
|
13
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
it "should get call associations if object and association are both in eager_loadings and call_object_associations" do
|
|
17
17
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
|
18
18
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
|
19
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.
|
|
19
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to eq([:association])
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
it "should not get call associations if not exist in call_object_associations" do
|
|
23
23
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
|
24
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.
|
|
24
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
context ".diff_object_associations" do
|
|
29
29
|
it "should return associations not exist in call_association" do
|
|
30
|
-
expect(UnusedEagerLoading.send(:diff_object_associations, @post.
|
|
30
|
+
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to eq([:association])
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "should return empty if associations exist in call_association" do
|
|
34
34
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
|
35
35
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
|
36
|
-
expect(UnusedEagerLoading.send(:diff_object_associations, @post.
|
|
36
|
+
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -48,7 +48,7 @@ module Bullet
|
|
|
48
48
|
UnusedEagerLoading.add_object_associations(@post, :association)
|
|
49
49
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
|
50
50
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
|
51
|
-
expect(UnusedEagerLoading.send(:diff_object_associations, @post.
|
|
51
|
+
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
|
52
52
|
expect(UnusedEagerLoading).not_to receive(:create_notification).with("Post", [:association])
|
|
53
53
|
UnusedEagerLoading.check_unused_preload_associations
|
|
54
54
|
end
|
|
@@ -57,30 +57,30 @@ module Bullet
|
|
|
57
57
|
context ".add_eager_loadings" do
|
|
58
58
|
it "should add objects, associations pair when eager_loadings are empty" do
|
|
59
59
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :associations)
|
|
60
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
60
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :associations)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "should add objects, associations pair for existing eager_loadings" do
|
|
64
64
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
|
|
65
65
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
|
|
66
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
67
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
66
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association1)
|
|
67
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association2)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it "should merge objects, associations pair for existing eager_loadings" do
|
|
71
71
|
UnusedEagerLoading.add_eager_loadings([@post], :association1)
|
|
72
72
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
|
|
73
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
74
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
75
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
73
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
|
|
74
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
|
|
75
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association2)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
it "should delete objects, associations pair for existing eager_loadings" do
|
|
79
79
|
UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
|
|
80
80
|
UnusedEagerLoading.add_eager_loadings([@post], :association2)
|
|
81
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
82
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.
|
|
83
|
-
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.
|
|
81
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association1)
|
|
82
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key], :association2)
|
|
83
|
+
expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post2.bullet_key], :association1)
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
end
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Object do
|
|
4
|
-
context "
|
|
4
|
+
context "bullet_key" do
|
|
5
5
|
it "should return class and id composition" do
|
|
6
6
|
post = Post.first
|
|
7
|
-
expect(post.
|
|
7
|
+
expect(post.bullet_key).to eq("Post:#{post.id}")
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
if mongoid?
|
|
11
11
|
it "should return class with namesapce and id composition" do
|
|
12
12
|
post = Mongoid::Post.first
|
|
13
|
-
expect(post.
|
|
13
|
+
expect(post.bullet_key).to eq("Mongoid::Post:#{post.id}")
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
context "primary_key_value" do
|
|
19
|
+
it "should return id" do
|
|
20
|
+
post = Post.first
|
|
21
|
+
expect(post.primary_key_value).to eq(post.id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should return primary key value" do
|
|
25
|
+
post = Post.first
|
|
26
|
+
Post.primary_key = 'name'
|
|
27
|
+
expect(post.primary_key_value).to eq(post.name)
|
|
28
|
+
Post.primary_key = 'id'
|
|
29
|
+
end
|
|
30
|
+
end
|
|
17
31
|
end
|
|
@@ -22,6 +22,35 @@ module Bullet
|
|
|
22
22
|
user = `whoami`.chomp
|
|
23
23
|
expect(subject.whoami).to eq("user: #{user}")
|
|
24
24
|
end
|
|
25
|
+
|
|
26
|
+
it "should leverage ENV parameter" do
|
|
27
|
+
temp_env_variable("USER", "bogus") do
|
|
28
|
+
expect(subject.whoami).to eq("user: bogus")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should return blank if no user available" do
|
|
33
|
+
temp_env_variable("USER","") do
|
|
34
|
+
expect(subject).to receive(:`).with("whoami").and_return("")
|
|
35
|
+
expect(subject.whoami).to eq("")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should return blank if whoami is not available" do
|
|
40
|
+
temp_env_variable("USER","") do
|
|
41
|
+
expect(subject).to receive(:`).with("whoami").and_raise(Errno::ENOENT)
|
|
42
|
+
expect(subject.whoami).to eq("")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def temp_env_variable(name, value)
|
|
47
|
+
old_value = ENV[name]
|
|
48
|
+
ENV[name] = value
|
|
49
|
+
yield
|
|
50
|
+
ensure
|
|
51
|
+
ENV[name] = old_value
|
|
52
|
+
end
|
|
53
|
+
|
|
25
54
|
end
|
|
26
55
|
|
|
27
56
|
context "#body_with_caller" do
|
|
@@ -47,6 +76,14 @@ module Bullet
|
|
|
47
76
|
allow(subject).to receive(:body_with_caller).and_return("body_with_caller")
|
|
48
77
|
expect(subject.full_notice).to eq("whoami\nurl\ntitle\nbody_with_caller")
|
|
49
78
|
end
|
|
79
|
+
|
|
80
|
+
it "should return url + title + body_with_caller" do
|
|
81
|
+
allow(subject).to receive(:whoami).and_return("")
|
|
82
|
+
allow(subject).to receive(:url).and_return("url")
|
|
83
|
+
allow(subject).to receive(:title).and_return("title")
|
|
84
|
+
allow(subject).to receive(:body_with_caller).and_return("body_with_caller")
|
|
85
|
+
expect(subject.full_notice).to eq("url\ntitle\nbody_with_caller")
|
|
86
|
+
end
|
|
50
87
|
end
|
|
51
88
|
|
|
52
89
|
context "#notification_data" do
|
|
@@ -5,18 +5,18 @@ module Bullet
|
|
|
5
5
|
describe Object do
|
|
6
6
|
let(:post) { Post.first }
|
|
7
7
|
let(:another_post) { Post.last }
|
|
8
|
-
subject { Object.new.tap { |object| object.add(post.
|
|
8
|
+
subject { Object.new.tap { |object| object.add(post.bullet_key) } }
|
|
9
9
|
|
|
10
10
|
context "#include?" do
|
|
11
11
|
it "should include the object" do
|
|
12
|
-
expect(subject).to be_include(post.
|
|
12
|
+
expect(subject).to be_include(post.bullet_key)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
context "#add" do
|
|
17
17
|
it "should add an object" do
|
|
18
|
-
subject.add(another_post.
|
|
19
|
-
expect(subject).to be_include(another_post.
|
|
18
|
+
subject.add(another_post.bullet_key)
|
|
19
|
+
expect(subject).to be_include(another_post.bullet_key)
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
data/spec/bullet_spec.rb
CHANGED
|
@@ -26,8 +26,8 @@ describe Bullet, focused: true do
|
|
|
26
26
|
|
|
27
27
|
context 'enable Bullet again without patching again the orms' do
|
|
28
28
|
before do
|
|
29
|
-
Bullet::Mongoid.
|
|
30
|
-
Bullet::ActiveRecord.
|
|
29
|
+
expect(Bullet::Mongoid).not_to receive(:enable) if defined? Bullet::Mongoid
|
|
30
|
+
expect(Bullet::ActiveRecord).not_to receive(:enable) if defined? Bullet::ActiveRecord
|
|
31
31
|
Bullet.enable = true
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -39,7 +39,7 @@ if !mongoid? && active_record3?
|
|
|
39
39
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
it "should detect non preload comment => post with inverse_of" do
|
|
42
|
+
it "should not detect non preload comment => post with inverse_of" do
|
|
43
43
|
Post.includes(:comments).each do |post|
|
|
44
44
|
post.comments.each do |comment|
|
|
45
45
|
comment.name
|
|
@@ -371,7 +371,7 @@ if !mongoid? && active_record3?
|
|
|
371
371
|
comment.post.writer.newspaper.name
|
|
372
372
|
end
|
|
373
373
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
374
|
-
Bullet::Detector::Association.
|
|
374
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
375
375
|
|
|
376
376
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Writer, :newspaper)
|
|
377
377
|
end
|
|
@@ -369,7 +369,7 @@ if !mongoid? && active_record4?
|
|
|
369
369
|
comment.post.writer.newspaper.name
|
|
370
370
|
end
|
|
371
371
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
372
|
-
Bullet::Detector::Association.
|
|
372
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
|
373
373
|
|
|
374
374
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Writer, :newspaper)
|
|
375
375
|
end
|