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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +82 -0
  3. data/CHANGELOG.md +45 -0
  4. data/Gemfile.rails-6.0 +1 -1
  5. data/Gemfile.rails-6.1 +15 -0
  6. data/Gemfile.rails-7.0 +10 -0
  7. data/README.md +37 -25
  8. data/lib/bullet/active_job.rb +5 -1
  9. data/lib/bullet/active_record41.rb +1 -0
  10. data/lib/bullet/active_record42.rb +1 -0
  11. data/lib/bullet/active_record5.rb +1 -1
  12. data/lib/bullet/active_record52.rb +23 -18
  13. data/lib/bullet/active_record60.rb +23 -18
  14. data/lib/bullet/active_record61.rb +272 -0
  15. data/lib/bullet/active_record70.rb +275 -0
  16. data/lib/bullet/bullet_xhr.js +18 -17
  17. data/lib/bullet/dependency.rb +16 -0
  18. data/lib/bullet/detector/base.rb +2 -1
  19. data/lib/bullet/detector/counter_cache.rb +2 -2
  20. data/lib/bullet/detector/n_plus_one_query.rb +5 -5
  21. data/lib/bullet/detector/unused_eager_loading.rb +2 -2
  22. data/lib/bullet/mongoid4x.rb +1 -1
  23. data/lib/bullet/mongoid5x.rb +1 -1
  24. data/lib/bullet/mongoid6x.rb +1 -1
  25. data/lib/bullet/mongoid7x.rb +24 -7
  26. data/lib/bullet/notification.rb +2 -1
  27. data/lib/bullet/rack.rb +28 -19
  28. data/lib/bullet/stack_trace_filter.rb +7 -9
  29. data/lib/bullet/version.rb +1 -1
  30. data/lib/bullet.rb +29 -28
  31. data/lib/generators/bullet/install_generator.rb +22 -25
  32. data/perf/benchmark.rb +4 -1
  33. data/spec/bullet/detector/counter_cache_spec.rb +1 -1
  34. data/spec/bullet/detector/n_plus_one_query_spec.rb +1 -1
  35. data/spec/bullet/detector/unused_eager_loading_spec.rb +10 -10
  36. data/spec/bullet/ext/object_spec.rb +1 -1
  37. data/spec/bullet/notification/base_spec.rb +4 -4
  38. data/spec/bullet/notification/n_plus_one_query_spec.rb +1 -3
  39. data/spec/bullet/rack_spec.rb +135 -9
  40. data/spec/bullet_spec.rb +15 -15
  41. data/spec/integration/active_record/association_spec.rb +64 -10
  42. data/spec/integration/counter_cache_spec.rb +4 -4
  43. data/spec/integration/mongoid/association_spec.rb +4 -4
  44. data/spec/models/attachment.rb +5 -0
  45. data/spec/models/deal.rb +5 -0
  46. data/spec/models/folder.rb +2 -1
  47. data/spec/models/group.rb +2 -1
  48. data/spec/models/page.rb +2 -1
  49. data/spec/models/post.rb +2 -0
  50. data/spec/models/role.rb +7 -0
  51. data/spec/models/submission.rb +1 -0
  52. data/spec/models/user.rb +2 -0
  53. data/spec/models/writer.rb +2 -1
  54. data/spec/spec_helper.rb +0 -2
  55. data/spec/support/mongo_seed.rb +1 -0
  56. data/spec/support/sqlite_seed.rb +38 -0
  57. data/test.sh +2 -0
  58. metadata +17 -7
  59. 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.assocations is called.
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.get_whitelist_associations(:n_plus_one_query, klazz)
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 assocations
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.get_whitelist_associations(:unused_eager_loading, klazz)
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)
@@ -23,7 +23,7 @@ module Bullet
23
23
  end
24
24
 
25
25
  def each(&block)
26
- return to_enum unless block_given?
26
+ return to_enum unless block
27
27
 
28
28
  records = []
29
29
  origin_each { |record| records << record }
@@ -23,7 +23,7 @@ module Bullet
23
23
  end
24
24
 
25
25
  def each(&block)
26
- return to_enum unless block_given?
26
+ return to_enum unless block
27
27
 
28
28
  records = []
29
29
  origin_each { |record| records << record }
@@ -23,7 +23,7 @@ module Bullet
23
23
  end
24
24
 
25
25
  def each(&block)
26
- return to_enum unless block_given?
26
+ return to_enum unless block
27
27
 
28
28
  records = []
29
29
  origin_each { |record| records << record }
@@ -25,14 +25,31 @@ module Bullet
25
25
  def each(&block)
26
26
  return to_enum unless block_given?
27
27
 
28
- records = []
29
- origin_each { |record| records << record }
30
- if records.length > 1
31
- Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
32
- elsif records.size == 1
33
- Bullet::Detector::NPlusOneQuery.add_impossible_object(records.first)
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
- records.each(&block)
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)
@@ -7,6 +7,7 @@ module Bullet
7
7
  autoload :NPlusOneQuery, 'bullet/notification/n_plus_one_query'
8
8
  autoload :CounterCache, 'bullet/notification/counter_cache'
9
9
 
10
- class UnoptimizedQueryError < StandardError; end
10
+ class UnoptimizedQueryError < StandardError
11
+ end
11
12
  end
12
13
  end
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 !Bullet.skip_html_injection? && !file?(headers) && !sse?(headers) && !empty?(response) && status == 200
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
- response_body = append_to_html_body(response_body, xhr_script)
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
- else
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
- "<div #{footer_div_attributes}>" + footer_header + '<br>' + Bullet.footer_info.uniq.join('<br>') + '</div>'
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 * 1_024
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') && response_body(response).include?('<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
- else
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 footer_div_attributes
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
- id="bullet-footer" data-is-bullet-footer ondblclick="this.parentNode.removeChild(this);" style="position: fixed; bottom: 0pt; left: 0pt; cursor: pointer; border-style: solid; border-color: rgb(153, 153, 153);
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 footer_header
102
- cancel_button =
103
- "<span onclick='this.parentNode.remove()' style='position:absolute; right: 10px; top: 0px; font-weight: bold; color: #333;'>&times;</span>"
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>#{cancel_button}"
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
- Bullet.stacktrace_includes.any? { |include_pattern| pattern_matches?(location, include_pattern) }
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
- ruby_19? ? location : location.absolute_path.to_s
53
+ IS_RUBY_19 ? location : location.absolute_path.to_s
51
54
  end
52
55
 
53
56
  def select_caller_locations
54
- if ruby_19?
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bullet
4
- VERSION = '6.1.0'
4
+ VERSION = '7.0.3'
5
5
  end
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 :whitelist
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 = UniformNotifier::AVAILABLE_NOTIFIERS.map { |notifier| "#{notifier}=" }
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
- reset_whitelist
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 add_whitelist(options)
100
- reset_whitelist
101
- @whitelist[options[:type]][options[:class_name]] ||= []
102
- @whitelist[options[:type]][options[:class_name]] << options[:association].to_sym
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 delete_whitelist(options)
106
- reset_whitelist
107
- @whitelist[options[:type]][options[:class_name]] ||= []
108
- @whitelist[options[:type]][options[:class_name]].delete(options[:association].to_sym)
109
- @whitelist[options[:type]].delete_if { |_key, val| val.empty? }
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 get_whitelist_associations(type, class_name)
113
- Array(@whitelist[type][class_name])
111
+ def get_safelist_associations(type, class_name)
112
+ Array.wrap(@safelist[type][class_name])
114
113
  end
115
114
 
116
- def reset_whitelist
117
- @whitelist ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
115
+ def reset_safelist
116
+ @safelist ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
118
117
  end
119
118
 
120
- def clear_whitelist
121
- @whitelist = nil
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] == TRUE
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 skip_html_injection?
244
- @skip_html_injection || false
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
- <<-"FILE"
14
-
15
- config.after_initialize do
16
- Bullet.enable = true
17
- Bullet.alert = true
18
- Bullet.bullet_logger = true
19
- Bullet.console = true
20
- # Bullet.growl = true
21
- Bullet.rails_logger = true
22
- Bullet.add_footer = true
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
- if yes?('Would you like to enable bullet in test environment? (y/n)')
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
- say 'Enabled bullet in config/environments/test.rb'
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', database: 'bullet_benchmark', server: '/tmp/mysql.socket', username: 'root'
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 true when object is possible, and impossible' do
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, :associatio2)).to eq false
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(%i[association]))).to be_empty
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(%i[association]))).to eq(
23
- %i[association]
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(%i[association]))).to be_empty
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(%i[association]))).to eq(
36
- %i[association]
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(%i[association]))
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', %i[association])
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(%i[association]))
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', %i[association])
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 namesapce and id composition' do
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