bullet 6.1.0 → 7.0.3
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/.github/workflows/main.yml +82 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile.rails-6.0 +1 -1
- data/Gemfile.rails-6.1 +15 -0
- data/Gemfile.rails-7.0 +10 -0
- data/README.md +37 -25
- data/lib/bullet/active_job.rb +5 -1
- data/lib/bullet/active_record41.rb +1 -0
- data/lib/bullet/active_record42.rb +1 -0
- data/lib/bullet/active_record5.rb +1 -1
- data/lib/bullet/active_record52.rb +23 -18
- data/lib/bullet/active_record60.rb +23 -18
- data/lib/bullet/active_record61.rb +272 -0
- data/lib/bullet/active_record70.rb +275 -0
- data/lib/bullet/bullet_xhr.js +18 -17
- data/lib/bullet/dependency.rb +16 -0
- data/lib/bullet/detector/base.rb +2 -1
- data/lib/bullet/detector/counter_cache.rb +2 -2
- data/lib/bullet/detector/n_plus_one_query.rb +5 -5
- data/lib/bullet/detector/unused_eager_loading.rb +2 -2
- data/lib/bullet/mongoid4x.rb +1 -1
- data/lib/bullet/mongoid5x.rb +1 -1
- data/lib/bullet/mongoid6x.rb +1 -1
- data/lib/bullet/mongoid7x.rb +24 -7
- data/lib/bullet/notification.rb +2 -1
- data/lib/bullet/rack.rb +28 -19
- data/lib/bullet/stack_trace_filter.rb +7 -9
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +29 -28
- data/lib/generators/bullet/install_generator.rb +22 -25
- data/perf/benchmark.rb +4 -1
- data/spec/bullet/detector/counter_cache_spec.rb +1 -1
- data/spec/bullet/detector/n_plus_one_query_spec.rb +1 -1
- data/spec/bullet/detector/unused_eager_loading_spec.rb +10 -10
- data/spec/bullet/ext/object_spec.rb +1 -1
- data/spec/bullet/notification/base_spec.rb +4 -4
- data/spec/bullet/notification/n_plus_one_query_spec.rb +1 -3
- data/spec/bullet/rack_spec.rb +135 -9
- data/spec/bullet_spec.rb +15 -15
- data/spec/integration/active_record/association_spec.rb +64 -10
- data/spec/integration/counter_cache_spec.rb +4 -4
- data/spec/integration/mongoid/association_spec.rb +4 -4
- data/spec/models/attachment.rb +5 -0
- data/spec/models/deal.rb +5 -0
- data/spec/models/folder.rb +2 -1
- data/spec/models/group.rb +2 -1
- data/spec/models/page.rb +2 -1
- data/spec/models/post.rb +2 -0
- data/spec/models/role.rb +7 -0
- data/spec/models/submission.rb +1 -0
- data/spec/models/user.rb +2 -0
- data/spec/models/writer.rb +2 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/mongo_seed.rb +1 -0
- data/spec/support/sqlite_seed.rb +38 -0
- data/test.sh +2 -0
- metadata +17 -7
- data/.travis.yml +0 -33
@@ -7,7 +7,7 @@ module Bullet
|
|
7
7
|
extend StackTraceFilter
|
8
8
|
|
9
9
|
class << self
|
10
|
-
# executed when object.
|
10
|
+
# executed when object.associations is called.
|
11
11
|
# first, it keeps this method call for object.association.
|
12
12
|
# then, it checks if this associations call is unpreload.
|
13
13
|
# if it is, keeps this unpreload associations and caller.
|
@@ -33,8 +33,9 @@ module Bullet
|
|
33
33
|
return unless Bullet.start?
|
34
34
|
return unless Bullet.n_plus_one_query_enable?
|
35
35
|
|
36
|
-
objects = Array(object_or_objects)
|
36
|
+
objects = Array.wrap(object_or_objects)
|
37
37
|
return if objects.map(&:bullet_primary_key_value).compact.empty?
|
38
|
+
return if objects.all? { |obj| obj.class.name =~ /^HABTM_/ }
|
38
39
|
|
39
40
|
Bullet.debug(
|
40
41
|
'Detector::NPlusOneQuery#add_possible_objects',
|
@@ -84,8 +85,7 @@ module Bullet
|
|
84
85
|
# associations == v comparison order is important here because
|
85
86
|
# v variable might be a squeel node where :== method is redefined,
|
86
87
|
# so it does not compare values at all and return unexpected results
|
87
|
-
result =
|
88
|
-
v.is_a?(Hash) ? v.key?(associations) : associations == v
|
88
|
+
result = v.is_a?(Hash) ? v.key?(associations) : associations == v
|
89
89
|
return true if result
|
90
90
|
end
|
91
91
|
|
@@ -95,7 +95,7 @@ module Bullet
|
|
95
95
|
private
|
96
96
|
|
97
97
|
def create_notification(callers, klazz, associations)
|
98
|
-
notify_associations = Array(associations) - Bullet.
|
98
|
+
notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:n_plus_one_query, klazz)
|
99
99
|
|
100
100
|
if notify_associations.present?
|
101
101
|
notice = Bullet::Notification::NPlusOneQuery.new(callers, klazz, notify_associations)
|
@@ -10,7 +10,7 @@ module Bullet
|
|
10
10
|
# check if there are unused preload associations.
|
11
11
|
# get related_objects from eager_loadings associated with object and associations
|
12
12
|
# get call_object_association from associations of call_object_associations whose object is in related_objects
|
13
|
-
# if association not in call_object_association, then the object => association - call_object_association is ununsed preload
|
13
|
+
# if association not in call_object_association, then the object => association - call_object_association is ununsed preload associations
|
14
14
|
def check_unused_preload_associations
|
15
15
|
return unless Bullet.start?
|
16
16
|
return unless Bullet.unused_eager_loading_enable?
|
@@ -65,7 +65,7 @@ module Bullet
|
|
65
65
|
private
|
66
66
|
|
67
67
|
def create_notification(callers, klazz, associations)
|
68
|
-
notify_associations = Array(associations) - Bullet.
|
68
|
+
notify_associations = Array.wrap(associations) - Bullet.get_safelist_associations(:unused_eager_loading, klazz)
|
69
69
|
|
70
70
|
if notify_associations.present?
|
71
71
|
notice = Bullet::Notification::UnusedEagerLoading.new(callers, klazz, notify_associations)
|
data/lib/bullet/mongoid4x.rb
CHANGED
data/lib/bullet/mongoid5x.rb
CHANGED
data/lib/bullet/mongoid6x.rb
CHANGED
data/lib/bullet/mongoid7x.rb
CHANGED
@@ -25,14 +25,31 @@ module Bullet
|
|
25
25
|
def each(&block)
|
26
26
|
return to_enum unless block_given?
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
first_document = nil
|
29
|
+
document_count = 0
|
30
|
+
|
31
|
+
origin_each do |document|
|
32
|
+
document_count += 1
|
33
|
+
|
34
|
+
if document_count == 1
|
35
|
+
first_document = document
|
36
|
+
elsif document_count == 2
|
37
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects([first_document, document])
|
38
|
+
yield(first_document)
|
39
|
+
first_document = nil
|
40
|
+
yield(document)
|
41
|
+
else
|
42
|
+
Bullet::Detector::NPlusOneQuery.add_possible_objects(document)
|
43
|
+
yield(document)
|
44
|
+
end
|
34
45
|
end
|
35
|
-
|
46
|
+
|
47
|
+
if document_count == 1
|
48
|
+
Bullet::Detector::NPlusOneQuery.add_impossible_object(first_document)
|
49
|
+
yield(first_document)
|
50
|
+
end
|
51
|
+
|
52
|
+
self
|
36
53
|
end
|
37
54
|
|
38
55
|
def eager_load(docs)
|
data/lib/bullet/notification.rb
CHANGED
data/lib/bullet/rack.rb
CHANGED
@@ -17,14 +17,16 @@ module Bullet
|
|
17
17
|
response_body = nil
|
18
18
|
|
19
19
|
if Bullet.notification?
|
20
|
-
if
|
20
|
+
if Bullet.inject_into_page? && !file?(headers) && !sse?(headers) && !empty?(response) && status == 200
|
21
21
|
if html_request?(headers, response)
|
22
22
|
response_body = response_body(response)
|
23
23
|
response_body = append_to_html_body(response_body, footer_note) if Bullet.add_footer
|
24
24
|
response_body = append_to_html_body(response_body, Bullet.gather_inline_notifications)
|
25
|
-
|
25
|
+
if Bullet.add_footer && !Bullet.skip_http_headers
|
26
|
+
response_body = append_to_html_body(response_body, xhr_script)
|
27
|
+
end
|
26
28
|
headers['Content-Length'] = response_body.bytesize.to_s
|
27
|
-
|
29
|
+
elsif !Bullet.skip_http_headers
|
28
30
|
set_header(headers, 'X-bullet-footer-text', Bullet.footer_info.uniq) if Bullet.add_footer
|
29
31
|
set_header(headers, 'X-bullet-console-text', Bullet.text_notifications) if Bullet.console_enabled?
|
30
32
|
end
|
@@ -40,12 +42,14 @@ module Bullet
|
|
40
42
|
def empty?(response)
|
41
43
|
# response may be ["Not Found"], ["Move Permanently"], etc, but
|
42
44
|
# those should not happen if the status is 200
|
45
|
+
return true if !response.respond_to?(:body) && !response.respond_to?(:first)
|
43
46
|
body = response_body(response)
|
44
47
|
body.nil? || body.empty?
|
45
48
|
end
|
46
49
|
|
47
50
|
def append_to_html_body(response_body, content)
|
48
51
|
body = response_body.dup
|
52
|
+
content = content.html_safe if content.respond_to?(:html_safe)
|
49
53
|
if body.include?('</body>')
|
50
54
|
position = body.rindex('</body>')
|
51
55
|
body.insert(position, content)
|
@@ -55,14 +59,14 @@ module Bullet
|
|
55
59
|
end
|
56
60
|
|
57
61
|
def footer_note
|
58
|
-
"<
|
62
|
+
"<details #{details_attributes}><summary #{summary_attributes}>Bullet Warnings</summary><div #{footer_content_attributes}>#{Bullet.footer_info.uniq.join('<br>')}#{footer_console_message}</div></details>"
|
59
63
|
end
|
60
64
|
|
61
65
|
def set_header(headers, header_name, header_array)
|
62
66
|
# Many proxy applications such as Nginx and AWS ELB limit
|
63
67
|
# the size a header to 8KB, so truncate the list of reports to
|
64
68
|
# be under that limit
|
65
|
-
header_array.pop while header_array.to_json.length > 8 *
|
69
|
+
header_array.pop while header_array.to_json.length > 8 * 1024
|
66
70
|
headers[header_name] = header_array.to_json
|
67
71
|
end
|
68
72
|
|
@@ -75,36 +79,41 @@ module Bullet
|
|
75
79
|
end
|
76
80
|
|
77
81
|
def html_request?(headers, response)
|
78
|
-
headers['Content-Type']&.include?('text/html')
|
82
|
+
headers['Content-Type']&.include?('text/html')
|
79
83
|
end
|
80
84
|
|
81
85
|
def response_body(response)
|
82
86
|
if response.respond_to?(:body)
|
83
87
|
Array === response.body ? response.body.first : response.body
|
84
|
-
|
88
|
+
elsif response.respond_to?(:first)
|
85
89
|
response.first
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
89
93
|
private
|
90
94
|
|
91
|
-
def
|
95
|
+
def details_attributes
|
96
|
+
<<~EOF
|
97
|
+
id="bullet-footer" data-is-bullet-footer
|
98
|
+
style="cursor: pointer; position: fixed; left: 0px; bottom: 0px; z-index: 9999; background: #fdf2f2; color: #9b1c1c; font-size: 12px; border-radius: 0px 8px 0px 0px; border: 1px solid #9b1c1c;"
|
99
|
+
EOF
|
100
|
+
end
|
101
|
+
|
102
|
+
def summary_attributes
|
92
103
|
<<~EOF
|
93
|
-
|
94
|
-
-moz-border-top-colors: none; -moz-border-right-colors: none; -moz-border-bottom-colors: none;
|
95
|
-
-moz-border-left-colors: none; -moz-border-image: none; border-width: 2pt 2pt 0px 0px;
|
96
|
-
padding: 3px 5px; border-radius: 0pt 10pt 0pt 0px; background: none repeat scroll 0% 0% rgba(200, 200, 200, 0.8);
|
97
|
-
color: rgb(119, 119, 119); font-size: 16px; font-family: 'Arial', sans-serif; z-index:9999;"
|
104
|
+
style="font-weight: 600; padding: 2px 8px"
|
98
105
|
EOF
|
99
106
|
end
|
100
107
|
|
101
|
-
def
|
102
|
-
|
103
|
-
|
108
|
+
def footer_content_attributes
|
109
|
+
<<~EOF
|
110
|
+
style="padding: 8px; border-top: 1px solid #9b1c1c;"
|
111
|
+
EOF
|
112
|
+
end
|
113
|
+
|
114
|
+
def footer_console_message
|
104
115
|
if Bullet.console_enabled?
|
105
|
-
"<span>See 'Uniform Notifier' in JS Console for Stacktrace</span
|
106
|
-
else
|
107
|
-
cancel_button
|
116
|
+
"<br/><span style='font-style: italic;'>See 'Uniform Notifier' in JS Console for Stacktrace</span>"
|
108
117
|
end
|
109
118
|
end
|
110
119
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require "bundler"
|
2
3
|
|
3
4
|
module Bullet
|
4
5
|
module StackTraceFilter
|
5
6
|
VENDOR_PATH = '/vendor'
|
7
|
+
IS_RUBY_19 = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0')
|
6
8
|
|
7
9
|
def caller_in_project
|
8
10
|
vendor_root = Bullet.app_root + VENDOR_PATH
|
@@ -10,8 +12,9 @@ module Bullet
|
|
10
12
|
select_caller_locations do |location|
|
11
13
|
caller_path = location_as_path(location)
|
12
14
|
caller_path.include?(Bullet.app_root) && !caller_path.include?(vendor_root) &&
|
13
|
-
!caller_path.include?(bundler_path) ||
|
14
|
-
|
15
|
+
!caller_path.include?(bundler_path) || Bullet.stacktrace_includes.any? { |include_pattern|
|
16
|
+
pattern_matches?(location, include_pattern)
|
17
|
+
}
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
@@ -47,20 +50,15 @@ module Bullet
|
|
47
50
|
end
|
48
51
|
|
49
52
|
def location_as_path(location)
|
50
|
-
|
53
|
+
IS_RUBY_19 ? location : location.absolute_path.to_s
|
51
54
|
end
|
52
55
|
|
53
56
|
def select_caller_locations
|
54
|
-
if
|
57
|
+
if IS_RUBY_19
|
55
58
|
caller.select { |caller_path| yield caller_path }
|
56
59
|
else
|
57
60
|
caller_locations.select { |location| yield location }
|
58
61
|
end
|
59
62
|
end
|
60
|
-
|
61
|
-
def ruby_19?
|
62
|
-
@ruby_19 = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0') if @ruby_19.nil?
|
63
|
-
@ruby_19
|
64
|
-
end
|
65
63
|
end
|
66
64
|
end
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
@@ -20,9 +20,6 @@ module Bullet
|
|
20
20
|
autoload :Registry, 'bullet/registry'
|
21
21
|
autoload :NotificationCollector, 'bullet/notification_collector'
|
22
22
|
|
23
|
-
BULLET_DEBUG = 'BULLET_DEBUG'
|
24
|
-
TRUE = 'true'
|
25
|
-
|
26
23
|
if defined?(Rails::Railtie)
|
27
24
|
class BulletRailtie < Rails::Railtie
|
28
25
|
initializer 'bullet.configure_rails_initialization' do |app|
|
@@ -38,10 +35,11 @@ module Bullet
|
|
38
35
|
:stacktrace_includes,
|
39
36
|
:stacktrace_excludes,
|
40
37
|
:skip_html_injection
|
41
|
-
attr_reader :
|
42
|
-
attr_accessor :add_footer, :orm_patches_applied
|
38
|
+
attr_reader :safelist
|
39
|
+
attr_accessor :add_footer, :orm_patches_applied, :skip_http_headers
|
43
40
|
|
44
|
-
available_notifiers =
|
41
|
+
available_notifiers =
|
42
|
+
UniformNotifier::AVAILABLE_NOTIFIERS.select { |notifier| notifier != :raise }.map { |notifier| "#{notifier}=" }
|
45
43
|
available_notifiers_options = { to: UniformNotifier }
|
46
44
|
delegate(*available_notifiers, **available_notifiers_options)
|
47
45
|
|
@@ -59,7 +57,7 @@ module Bullet
|
|
59
57
|
@enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
|
60
58
|
|
61
59
|
if enable?
|
62
|
-
|
60
|
+
reset_safelist
|
63
61
|
unless orm_patches_applied
|
64
62
|
self.orm_patches_applied = true
|
65
63
|
Bullet::Mongoid.enable if mongoid?
|
@@ -72,8 +70,9 @@ module Bullet
|
|
72
70
|
!!@enable
|
73
71
|
end
|
74
72
|
|
73
|
+
# Rails.root might be nil if `railties` is a dependency on a project that does not use Rails
|
75
74
|
def app_root
|
76
|
-
(defined?(::Rails.root) ? Rails.root.to_s : Dir.pwd).to_s
|
75
|
+
@app_root ||= (defined?(::Rails.root) && !::Rails.root.nil? ? Rails.root.to_s : Dir.pwd).to_s
|
77
76
|
end
|
78
77
|
|
79
78
|
def n_plus_one_query_enable?
|
@@ -89,36 +88,36 @@ module Bullet
|
|
89
88
|
end
|
90
89
|
|
91
90
|
def stacktrace_includes
|
92
|
-
@stacktrace_includes
|
91
|
+
@stacktrace_includes ||= []
|
93
92
|
end
|
94
93
|
|
95
94
|
def stacktrace_excludes
|
96
|
-
@stacktrace_excludes
|
95
|
+
@stacktrace_excludes ||= []
|
97
96
|
end
|
98
97
|
|
99
|
-
def
|
100
|
-
|
101
|
-
@
|
102
|
-
@
|
98
|
+
def add_safelist(options)
|
99
|
+
reset_safelist
|
100
|
+
@safelist[options[:type]][options[:class_name]] ||= []
|
101
|
+
@safelist[options[:type]][options[:class_name]] << options[:association].to_sym
|
103
102
|
end
|
104
103
|
|
105
|
-
def
|
106
|
-
|
107
|
-
@
|
108
|
-
@
|
109
|
-
@
|
104
|
+
def delete_safelist(options)
|
105
|
+
reset_safelist
|
106
|
+
@safelist[options[:type]][options[:class_name]] ||= []
|
107
|
+
@safelist[options[:type]][options[:class_name]].delete(options[:association].to_sym)
|
108
|
+
@safelist[options[:type]].delete_if { |_key, val| val.empty? }
|
110
109
|
end
|
111
110
|
|
112
|
-
def
|
113
|
-
Array(@
|
111
|
+
def get_safelist_associations(type, class_name)
|
112
|
+
Array.wrap(@safelist[type][class_name])
|
114
113
|
end
|
115
114
|
|
116
|
-
def
|
117
|
-
@
|
115
|
+
def reset_safelist
|
116
|
+
@safelist ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
|
118
117
|
end
|
119
118
|
|
120
|
-
def
|
121
|
-
@
|
119
|
+
def clear_safelist
|
120
|
+
@safelist = nil
|
122
121
|
end
|
123
122
|
|
124
123
|
def bullet_logger=(active)
|
@@ -132,7 +131,7 @@ module Bullet
|
|
132
131
|
end
|
133
132
|
|
134
133
|
def debug(title, message)
|
135
|
-
puts "[Bullet][#{title}] #{message}" if ENV[BULLET_DEBUG] ==
|
134
|
+
puts "[Bullet][#{title}] #{message}" if ENV['BULLET_DEBUG'] == 'true'
|
136
135
|
end
|
137
136
|
|
138
137
|
def start_request
|
@@ -240,8 +239,10 @@ module Bullet
|
|
240
239
|
UniformNotifier.active_notifiers.include?(UniformNotifier::JavascriptConsole)
|
241
240
|
end
|
242
241
|
|
243
|
-
def
|
244
|
-
@skip_html_injection
|
242
|
+
def inject_into_page?
|
243
|
+
return false if defined?(@skip_html_injection) && @skip_html_injection
|
244
|
+
|
245
|
+
console_enabled? || add_footer
|
245
246
|
end
|
246
247
|
|
247
248
|
private
|
@@ -10,40 +10,37 @@ module Bullet
|
|
10
10
|
|
11
11
|
def enable_in_development
|
12
12
|
environment(nil, env: 'development') do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
13
|
+
<<~FILE
|
14
|
+
config.after_initialize do
|
15
|
+
Bullet.enable = true
|
16
|
+
Bullet.alert = true
|
17
|
+
Bullet.bullet_logger = true
|
18
|
+
Bullet.console = true
|
19
|
+
Bullet.rails_logger = true
|
20
|
+
Bullet.add_footer = true
|
21
|
+
end
|
22
|
+
|
24
23
|
FILE
|
25
|
-
.strip
|
26
24
|
end
|
27
25
|
|
28
26
|
say 'Enabled bullet in config/environments/development.rb'
|
29
27
|
end
|
30
28
|
|
31
29
|
def enable_in_test
|
32
|
-
|
33
|
-
environment(nil, env: 'test') do
|
34
|
-
<<-"FILE"
|
35
|
-
|
36
|
-
config.after_initialize do
|
37
|
-
Bullet.enable = true
|
38
|
-
Bullet.bullet_logger = true
|
39
|
-
Bullet.raise = true # raise an error if n+1 query occurs
|
40
|
-
end
|
41
|
-
FILE
|
42
|
-
.strip
|
43
|
-
end
|
30
|
+
return unless yes?('Would you like to enable bullet in test environment? (y/n)')
|
44
31
|
|
45
|
-
|
32
|
+
environment(nil, env: 'test') do
|
33
|
+
<<~FILE
|
34
|
+
config.after_initialize do
|
35
|
+
Bullet.enable = true
|
36
|
+
Bullet.bullet_logger = true
|
37
|
+
Bullet.raise = true # raise an error if n+1 query occurs
|
38
|
+
end
|
39
|
+
|
40
|
+
FILE
|
46
41
|
end
|
42
|
+
|
43
|
+
say 'Enabled bullet in config/environments/test.rb'
|
47
44
|
end
|
48
45
|
end
|
49
46
|
end
|
data/perf/benchmark.rb
CHANGED
@@ -30,7 +30,10 @@ end
|
|
30
30
|
|
31
31
|
# create database bullet_benchmark;
|
32
32
|
ActiveRecord::Base.establish_connection(
|
33
|
-
adapter: 'mysql2',
|
33
|
+
adapter: 'mysql2',
|
34
|
+
database: 'bullet_benchmark',
|
35
|
+
server: '/tmp/mysql.socket',
|
36
|
+
username: 'root'
|
34
37
|
)
|
35
38
|
|
36
39
|
ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
@@ -47,7 +47,7 @@ module Bullet
|
|
47
47
|
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|
48
48
|
end
|
49
49
|
|
50
|
-
it 'should be
|
50
|
+
it 'should be false when object is possible, and impossible' do
|
51
51
|
CounterCache.add_possible_objects(@post1)
|
52
52
|
CounterCache.add_impossible_object(@post1)
|
53
53
|
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|
@@ -39,7 +39,7 @@ module Bullet
|
|
39
39
|
|
40
40
|
it 'should be false if object, association pair is not existed' do
|
41
41
|
NPlusOneQuery.add_object_associations(@post, :association1)
|
42
|
-
expect(NPlusOneQuery.association?(@post, :
|
42
|
+
expect(NPlusOneQuery.association?(@post, :association2)).to eq false
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -13,27 +13,27 @@ module Bullet
|
|
13
13
|
|
14
14
|
context '.call_associations' do
|
15
15
|
it 'should get empty array if eager_loadings' do
|
16
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(
|
16
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'should get call associations if object and association are both in eager_loadings and call_object_associations' do
|
20
20
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
21
21
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
22
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(
|
23
|
-
|
22
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to eq(
|
23
|
+
[:association]
|
24
24
|
)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should not get call associations if not exist in call_object_associations' do
|
28
28
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
29
|
-
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new(
|
29
|
+
expect(UnusedEagerLoading.send(:call_associations, @post.bullet_key, Set.new([:association]))).to be_empty
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
context '.diff_object_associations' do
|
34
34
|
it 'should return associations not exist in call_association' do
|
35
|
-
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(
|
36
|
-
|
35
|
+
expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to eq(
|
36
|
+
[:association]
|
37
37
|
)
|
38
38
|
end
|
39
39
|
|
@@ -41,7 +41,7 @@ module Bullet
|
|
41
41
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
42
42
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
43
43
|
expect(
|
44
|
-
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(
|
44
|
+
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))
|
45
45
|
).to be_empty
|
46
46
|
end
|
47
47
|
end
|
@@ -51,7 +51,7 @@ module Bullet
|
|
51
51
|
it 'should create notification if object_association_diff is not empty' do
|
52
52
|
UnusedEagerLoading.add_object_associations(@post, :association)
|
53
53
|
allow(UnusedEagerLoading).to receive(:caller_in_project).and_return(paths)
|
54
|
-
expect(UnusedEagerLoading).to receive(:create_notification).with(paths, 'Post',
|
54
|
+
expect(UnusedEagerLoading).to receive(:create_notification).with(paths, 'Post', [:association])
|
55
55
|
UnusedEagerLoading.check_unused_preload_associations
|
56
56
|
end
|
57
57
|
|
@@ -60,9 +60,9 @@ module Bullet
|
|
60
60
|
UnusedEagerLoading.add_eager_loadings([@post], :association)
|
61
61
|
UnusedEagerLoading.add_call_object_associations(@post, :association)
|
62
62
|
expect(
|
63
|
-
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new(
|
63
|
+
UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))
|
64
64
|
).to be_empty
|
65
|
-
expect(UnusedEagerLoading).not_to receive(:create_notification).with('Post',
|
65
|
+
expect(UnusedEagerLoading).not_to receive(:create_notification).with('Post', [:association])
|
66
66
|
UnusedEagerLoading.check_unused_preload_associations
|
67
67
|
end
|
68
68
|
end
|
@@ -10,7 +10,7 @@ describe Object do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
if mongoid?
|
13
|
-
it 'should return class with
|
13
|
+
it 'should return class with namespace and id composition' do
|
14
14
|
post = Mongoid::Post.first
|
15
15
|
expect(post.bullet_key).to eq("Mongoid::Post:#{post.id}")
|
16
16
|
end
|
@@ -74,8 +74,8 @@ module Bullet
|
|
74
74
|
it 'should send full_notice to notifier' do
|
75
75
|
notifier = double
|
76
76
|
allow(subject).to receive(:notifier).and_return(notifier)
|
77
|
-
allow(subject).to receive(:notification_data).and_return(foo: :bar)
|
78
|
-
expect(notifier).to receive(:inline_notify).with(foo: :bar)
|
77
|
+
allow(subject).to receive(:notification_data).and_return({ foo: :bar })
|
78
|
+
expect(notifier).to receive(:inline_notify).with({ foo: :bar })
|
79
79
|
subject.notify_inline
|
80
80
|
end
|
81
81
|
end
|
@@ -84,8 +84,8 @@ module Bullet
|
|
84
84
|
it 'should send full_out_of_channel to notifier' do
|
85
85
|
notifier = double
|
86
86
|
allow(subject).to receive(:notifier).and_return(notifier)
|
87
|
-
allow(subject).to receive(:notification_data).and_return(foo: :bar)
|
88
|
-
expect(notifier).to receive(:out_of_channel_notify).with(foo: :bar)
|
87
|
+
allow(subject).to receive(:notification_data).and_return({ foo: :bar })
|
88
|
+
expect(notifier).to receive(:out_of_channel_notify).with({ foo: :bar })
|
89
89
|
subject.notify_out_of_channel
|
90
90
|
end
|
91
91
|
end
|
@@ -21,9 +21,7 @@ module Bullet
|
|
21
21
|
)
|
22
22
|
end
|
23
23
|
it do
|
24
|
-
expect(subject.body).to eq(
|
25
|
-
" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])"
|
26
|
-
)
|
24
|
+
expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])")
|
27
25
|
end
|
28
26
|
it { expect(subject.title).to eq('USE eager loading in path') }
|
29
27
|
end
|