bullet 5.5.0 → 5.8.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/.travis.yml +1 -5
- data/CHANGELOG.md +31 -1
- data/Gemfile +6 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +15 -0
- data/Gemfile.rails-5.2 +15 -0
- data/Guardfile +2 -2
- data/Hacking.md +1 -1
- data/README.md +20 -23
- data/Rakefile +20 -21
- data/bullet.gemspec +20 -15
- data/lib/bullet/active_record4.rb +18 -14
- data/lib/bullet/active_record41.rb +16 -14
- data/lib/bullet/active_record42.rb +24 -22
- data/lib/bullet/active_record5.rb +102 -91
- data/lib/bullet/active_record52.rb +232 -0
- data/lib/bullet/dependency.rb +9 -1
- data/lib/bullet/detector/association.rb +17 -14
- data/lib/bullet/detector/base.rb +2 -0
- data/lib/bullet/detector/counter_cache.rb +14 -10
- data/lib/bullet/detector/n_plus_one_query.rb +21 -17
- data/lib/bullet/detector/unused_eager_loading.rb +30 -24
- data/lib/bullet/detector.rb +2 -0
- data/lib/bullet/ext/object.rb +6 -4
- data/lib/bullet/ext/string.rb +3 -1
- data/lib/bullet/mongoid4x.rb +7 -2
- data/lib/bullet/mongoid5x.rb +7 -2
- data/lib/bullet/mongoid6x.rb +11 -6
- data/lib/bullet/notification/base.rb +26 -19
- data/lib/bullet/notification/counter_cache.rb +3 -1
- data/lib/bullet/notification/n_plus_one_query.rb +7 -4
- data/lib/bullet/notification/unused_eager_loading.rb +7 -4
- data/lib/bullet/notification.rb +2 -0
- data/lib/bullet/notification_collector.rb +2 -1
- data/lib/bullet/rack.rb +22 -18
- data/lib/bullet/registry/association.rb +2 -0
- data/lib/bullet/registry/base.rb +2 -0
- data/lib/bullet/registry/object.rb +2 -0
- data/lib/bullet/registry.rb +2 -0
- data/lib/bullet/stack_trace_filter.rb +56 -18
- data/lib/bullet/version.rb +3 -2
- data/lib/bullet.rb +43 -33
- data/lib/generators/bullet/install_generator.rb +48 -0
- data/perf/benchmark.rb +12 -12
- data/rails/init.rb +2 -0
- data/spec/bullet/detector/association_spec.rb +6 -4
- data/spec/bullet/detector/base_spec.rb +2 -0
- data/spec/bullet/detector/counter_cache_spec.rb +13 -11
- data/spec/bullet/detector/n_plus_one_query_spec.rb +71 -46
- data/spec/bullet/detector/unused_eager_loading_spec.rb +21 -19
- data/spec/bullet/ext/object_spec.rb +10 -8
- data/spec/bullet/ext/string_spec.rb +7 -5
- data/spec/bullet/notification/base_spec.rb +39 -38
- data/spec/bullet/notification/counter_cache_spec.rb +5 -3
- data/spec/bullet/notification/n_plus_one_query_spec.rb +5 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +4 -2
- data/spec/bullet/notification_collector_spec.rb +12 -10
- data/spec/bullet/rack_spec.rb +48 -47
- data/spec/bullet/registry/association_spec.rb +12 -10
- data/spec/bullet/registry/base_spec.rb +22 -20
- data/spec/bullet/registry/object_spec.rb +6 -4
- data/spec/bullet_spec.rb +24 -3
- data/spec/integration/{active_record4 → active_record}/association_spec.rb +176 -114
- data/spec/integration/counter_cache_spec.rb +15 -13
- data/spec/integration/mongoid/association_spec.rb +35 -33
- data/spec/models/address.rb +2 -0
- data/spec/models/author.rb +2 -0
- data/spec/models/base_user.rb +2 -0
- data/spec/models/category.rb +2 -0
- data/spec/models/city.rb +2 -0
- data/spec/models/client.rb +4 -0
- data/spec/models/comment.rb +3 -1
- data/spec/models/company.rb +2 -0
- data/spec/models/country.rb +2 -0
- data/spec/models/document.rb +4 -2
- data/spec/models/entry.rb +2 -0
- data/spec/models/firm.rb +3 -0
- data/spec/models/folder.rb +2 -0
- data/spec/models/group.rb +4 -0
- data/spec/models/mongoid/address.rb +3 -1
- data/spec/models/mongoid/category.rb +4 -2
- data/spec/models/mongoid/comment.rb +3 -1
- data/spec/models/mongoid/company.rb +3 -1
- data/spec/models/mongoid/entry.rb +3 -1
- data/spec/models/mongoid/post.rb +6 -4
- data/spec/models/mongoid/user.rb +2 -0
- data/spec/models/newspaper.rb +3 -1
- data/spec/models/page.rb +2 -0
- data/spec/models/person.rb +2 -0
- data/spec/models/pet.rb +2 -0
- data/spec/models/post.rb +17 -0
- data/spec/models/relationship.rb +2 -0
- data/spec/models/reply.rb +2 -0
- data/spec/models/student.rb +2 -0
- data/spec/models/submission.rb +2 -0
- data/spec/models/teacher.rb +2 -0
- data/spec/models/user.rb +2 -0
- data/spec/models/writer.rb +2 -0
- data/spec/spec_helper.rb +15 -13
- data/spec/support/bullet_ext.rb +2 -0
- data/spec/support/mongo_seed.rb +36 -42
- data/spec/support/rack_double.rb +13 -19
- data/spec/support/sqlite_seed.rb +84 -76
- data/tasks/bullet_tasks.rake +4 -2
- data/test.sh +2 -0
- data/update.sh +2 -0
- metadata +17 -11
- data/spec/integration/active_record5/association_spec.rb +0 -768
data/lib/bullet/registry.rb
CHANGED
|
@@ -1,34 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Bullet
|
|
2
4
|
module StackTraceFilter
|
|
3
|
-
VENDOR_PATH =
|
|
5
|
+
VENDOR_PATH = '/vendor'
|
|
4
6
|
|
|
5
7
|
def caller_in_project
|
|
6
8
|
app_root = rails? ? Rails.root.to_s : Dir.pwd
|
|
7
9
|
vendor_root = app_root + VENDOR_PATH
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
caller_path.include?(include_pattern)
|
|
14
|
-
when Regexp
|
|
15
|
-
caller_path =~ include_pattern
|
|
16
|
-
end
|
|
17
|
-
end
|
|
10
|
+
bundler_path = Bundler.bundle_path.to_s
|
|
11
|
+
select_caller_locations do |location|
|
|
12
|
+
caller_path = location_as_path(location)
|
|
13
|
+
caller_path.include?(app_root) && !caller_path.include?(vendor_root) && !caller_path.include?(bundler_path) ||
|
|
14
|
+
Bullet.stacktrace_includes.any? { |include_pattern| pattern_matches?(location, include_pattern) }
|
|
18
15
|
end
|
|
19
16
|
end
|
|
20
17
|
|
|
21
18
|
def excluded_stacktrace_path?
|
|
22
19
|
Bullet.stacktrace_excludes.any? do |exclude_pattern|
|
|
23
|
-
caller_in_project.any?
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
caller_in_project.any? { |location| pattern_matches?(location, exclude_pattern) }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def pattern_matches?(location, pattern)
|
|
27
|
+
path = location_as_path(location)
|
|
28
|
+
case pattern
|
|
29
|
+
when Array
|
|
30
|
+
pattern_path = pattern.first
|
|
31
|
+
filter = pattern.last
|
|
32
|
+
return false unless pattern_matches?(location, pattern_path)
|
|
33
|
+
|
|
34
|
+
case filter
|
|
35
|
+
when Range
|
|
36
|
+
filter.include?(location.lineno)
|
|
37
|
+
when Integer
|
|
38
|
+
filter == location.lineno
|
|
39
|
+
when String
|
|
40
|
+
filter == location.base_label
|
|
30
41
|
end
|
|
42
|
+
when String
|
|
43
|
+
path.include?(pattern)
|
|
44
|
+
when Regexp
|
|
45
|
+
path =~ pattern
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def location_as_path(location)
|
|
50
|
+
ruby_19? ? location : location.absolute_path.to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def select_caller_locations
|
|
54
|
+
if ruby_19?
|
|
55
|
+
caller.select do |caller_path|
|
|
56
|
+
yield caller_path
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
caller_locations.select do |location|
|
|
60
|
+
yield location
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def ruby_19?
|
|
66
|
+
if @ruby_19.nil?
|
|
67
|
+
@ruby_19 = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.0.0')
|
|
31
68
|
end
|
|
69
|
+
@ruby_19
|
|
32
70
|
end
|
|
33
71
|
end
|
|
34
72
|
end
|
data/lib/bullet/version.rb
CHANGED
data/lib/bullet.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
|
2
4
|
require 'set'
|
|
3
5
|
require 'uniform_notifier'
|
|
4
6
|
require 'bullet/ext/object'
|
|
@@ -17,33 +19,33 @@ module Bullet
|
|
|
17
19
|
autoload :Registry, 'bullet/registry'
|
|
18
20
|
autoload :NotificationCollector, 'bullet/notification_collector'
|
|
19
21
|
|
|
20
|
-
BULLET_DEBUG = 'BULLET_DEBUG'
|
|
21
|
-
TRUE = 'true'
|
|
22
|
+
BULLET_DEBUG = 'BULLET_DEBUG'
|
|
23
|
+
TRUE = 'true'
|
|
22
24
|
|
|
23
25
|
if defined? Rails::Railtie
|
|
24
26
|
class BulletRailtie < Rails::Railtie
|
|
25
|
-
initializer
|
|
27
|
+
initializer 'bullet.configure_rails_initialization' do |app|
|
|
26
28
|
app.middleware.use Bullet::Rack
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
class << self
|
|
32
|
-
attr_writer :
|
|
33
|
-
attr_reader :
|
|
34
|
+
attr_writer :n_plus_one_query_enable, :unused_eager_loading_enable, :counter_cache_enable, :stacktrace_includes, :stacktrace_excludes
|
|
35
|
+
attr_reader :whitelist
|
|
34
36
|
attr_accessor :add_footer, :orm_pathches_applied
|
|
35
37
|
|
|
36
38
|
available_notifiers = UniformNotifier::AVAILABLE_NOTIFIERS.map { |notifier| "#{notifier}=" }
|
|
37
|
-
available_notifiers << { :
|
|
38
|
-
delegate
|
|
39
|
+
available_notifiers << { to: UniformNotifier }
|
|
40
|
+
delegate(*available_notifiers)
|
|
39
41
|
|
|
40
42
|
def raise=(should_raise)
|
|
41
|
-
UniformNotifier.raise=(should_raise ? Notification::UnoptimizedQueryError : false)
|
|
43
|
+
UniformNotifier.raise = (should_raise ? Notification::UnoptimizedQueryError : false)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
DETECTORS = [
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
DETECTORS = [Bullet::Detector::NPlusOneQuery,
|
|
47
|
+
Bullet::Detector::UnusedEagerLoading,
|
|
48
|
+
Bullet::Detector::CounterCache].freeze
|
|
47
49
|
|
|
48
50
|
def enable=(enable)
|
|
49
51
|
@enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
|
|
@@ -62,15 +64,15 @@ module Bullet
|
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def n_plus_one_query_enable?
|
|
65
|
-
|
|
67
|
+
enable? && !!@n_plus_one_query_enable
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def unused_eager_loading_enable?
|
|
69
|
-
|
|
71
|
+
enable? && !!@unused_eager_loading_enable
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
def counter_cache_enable?
|
|
73
|
-
|
|
75
|
+
enable? && !!@counter_cache_enable
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
def stacktrace_includes
|
|
@@ -87,12 +89,19 @@ module Bullet
|
|
|
87
89
|
@whitelist[options[:type]][options[:class_name]] << options[:association].to_sym
|
|
88
90
|
end
|
|
89
91
|
|
|
92
|
+
def delete_whitelist(options)
|
|
93
|
+
reset_whitelist
|
|
94
|
+
@whitelist[options[:type]][options[:class_name]] ||= []
|
|
95
|
+
@whitelist[options[:type]][options[:class_name]].delete(options[:association].to_sym)
|
|
96
|
+
@whitelist[options[:type]].delete_if { |_key, val| val.empty? }
|
|
97
|
+
end
|
|
98
|
+
|
|
90
99
|
def get_whitelist_associations(type, class_name)
|
|
91
100
|
Array(@whitelist[type][class_name])
|
|
92
101
|
end
|
|
93
102
|
|
|
94
103
|
def reset_whitelist
|
|
95
|
-
@whitelist ||= {:
|
|
104
|
+
@whitelist ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
|
|
96
105
|
end
|
|
97
106
|
|
|
98
107
|
def clear_whitelist
|
|
@@ -102,7 +111,7 @@ module Bullet
|
|
|
102
111
|
def bullet_logger=(active)
|
|
103
112
|
if active
|
|
104
113
|
require 'fileutils'
|
|
105
|
-
root_path =
|
|
114
|
+
root_path = (rails? ? Rails.root.to_s : Dir.pwd).to_s
|
|
106
115
|
FileUtils.mkdir_p(root_path + '/log')
|
|
107
116
|
bullet_log_file = File.open("#{root_path}/log/bullet.log", 'a+')
|
|
108
117
|
bullet_log_file.sync = true
|
|
@@ -154,6 +163,7 @@ module Bullet
|
|
|
154
163
|
|
|
155
164
|
def notification?
|
|
156
165
|
return unless start?
|
|
166
|
+
|
|
157
167
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
|
158
168
|
notification_collector.notifications_present?
|
|
159
169
|
end
|
|
@@ -163,7 +173,7 @@ module Bullet
|
|
|
163
173
|
for_each_active_notifier_with_notification do |notification|
|
|
164
174
|
responses << notification.notify_inline
|
|
165
175
|
end
|
|
166
|
-
responses.join(
|
|
176
|
+
responses.join("\n")
|
|
167
177
|
end
|
|
168
178
|
|
|
169
179
|
def perform_out_of_channel_notifications(env = {})
|
|
@@ -183,11 +193,10 @@ module Bullet
|
|
|
183
193
|
end
|
|
184
194
|
|
|
185
195
|
def warnings
|
|
186
|
-
notification_collector.collection.
|
|
196
|
+
notification_collector.collection.each_with_object({}) do |notification, warnings|
|
|
187
197
|
warning_type = notification.class.to_s.split(':').last.tableize
|
|
188
198
|
warnings[warning_type] ||= []
|
|
189
199
|
warnings[warning_type] << notification
|
|
190
|
-
warnings
|
|
191
200
|
end
|
|
192
201
|
end
|
|
193
202
|
|
|
@@ -211,23 +220,24 @@ module Bullet
|
|
|
211
220
|
end
|
|
212
221
|
|
|
213
222
|
private
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
223
|
+
|
|
224
|
+
def for_each_active_notifier_with_notification
|
|
225
|
+
UniformNotifier.active_notifiers.each do |notifier|
|
|
226
|
+
notification_collector.collection.each do |notification|
|
|
227
|
+
notification.notifier = notifier
|
|
228
|
+
yield notification
|
|
220
229
|
end
|
|
221
230
|
end
|
|
231
|
+
end
|
|
222
232
|
|
|
223
|
-
|
|
224
|
-
|
|
233
|
+
def build_request_uri(env)
|
|
234
|
+
return "#{env['REQUEST_METHOD']} #{env['REQUEST_URI']}" if env['REQUEST_URI']
|
|
225
235
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
end
|
|
236
|
+
if env['QUERY_STRING'].present?
|
|
237
|
+
"#{env['REQUEST_METHOD']} #{env['PATH_INFO']}?#{env['QUERY_STRING']}"
|
|
238
|
+
else
|
|
239
|
+
"#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
|
|
231
240
|
end
|
|
241
|
+
end
|
|
232
242
|
end
|
|
233
243
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bullet
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
6
|
+
desc <<~DESC
|
|
7
|
+
Description:
|
|
8
|
+
Enable bullet in development/test for your application.
|
|
9
|
+
DESC
|
|
10
|
+
|
|
11
|
+
def enable_in_development
|
|
12
|
+
environment(nil, env: 'development') do
|
|
13
|
+
<<-"FILE".strip
|
|
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
|
|
24
|
+
FILE
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
say 'Enabled bullet in config/environments/development.rb'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def enable_in_test
|
|
31
|
+
if yes?('Would you like to enable bullet in test environment? (y/n)')
|
|
32
|
+
environment(nil, env: 'test') do
|
|
33
|
+
<<-"FILE".strip
|
|
34
|
+
|
|
35
|
+
config.after_initialize do
|
|
36
|
+
Bullet.enable = true
|
|
37
|
+
Bullet.bullet_logger = true
|
|
38
|
+
Bullet.raise = true # raise an error if n+1 query occurs
|
|
39
|
+
end
|
|
40
|
+
FILE
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
say 'Enabled bullet in config/environments/test.rb'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/perf/benchmark.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH << 'lib'
|
|
2
4
|
require 'benchmark'
|
|
3
5
|
require 'rails'
|
|
4
6
|
require 'active_record'
|
|
@@ -27,13 +29,13 @@ class User < ActiveRecord::Base
|
|
|
27
29
|
end
|
|
28
30
|
|
|
29
31
|
# create database bullet_benchmark;
|
|
30
|
-
ActiveRecord::Base.establish_connection(:
|
|
32
|
+
ActiveRecord::Base.establish_connection(adapter: 'mysql2', database: 'bullet_benchmark', server: '/tmp/mysql.socket', username: 'root')
|
|
31
33
|
|
|
32
34
|
ActiveRecord::Base.connection.tables.each do |table|
|
|
33
35
|
ActiveRecord::Base.connection.drop_table(table)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
ActiveRecord::Schema.define(:
|
|
38
|
+
ActiveRecord::Schema.define(version: 1) do
|
|
37
39
|
create_table :posts do |t|
|
|
38
40
|
t.column :title, :string
|
|
39
41
|
t.column :body, :string
|
|
@@ -53,29 +55,28 @@ end
|
|
|
53
55
|
|
|
54
56
|
users_size = 100
|
|
55
57
|
posts_size = 1000
|
|
56
|
-
comments_size =
|
|
58
|
+
comments_size = 10_000
|
|
57
59
|
users = []
|
|
58
60
|
users_size.times do |i|
|
|
59
|
-
users << User.new(:
|
|
61
|
+
users << User.new(name: "user#{i}")
|
|
60
62
|
end
|
|
61
63
|
User.import users
|
|
62
64
|
users = User.all
|
|
63
65
|
|
|
64
66
|
posts = []
|
|
65
67
|
posts_size.times do |i|
|
|
66
|
-
posts << Post.new(:
|
|
68
|
+
posts << Post.new(title: "Title #{i}", body: "Body #{i}", user: users[i % 100])
|
|
67
69
|
end
|
|
68
70
|
Post.import posts
|
|
69
71
|
posts = Post.all
|
|
70
72
|
|
|
71
73
|
comments = []
|
|
72
74
|
comments_size.times do |i|
|
|
73
|
-
comments << Comment.new(:
|
|
75
|
+
comments << Comment.new(body: "Comment #{i}", post: posts[i % 1000], user: users[i % 100])
|
|
74
76
|
end
|
|
75
77
|
Comment.import comments
|
|
76
78
|
|
|
77
|
-
puts
|
|
78
|
-
|
|
79
|
+
puts 'Start benchmarking...'
|
|
79
80
|
|
|
80
81
|
Bullet.enable = true
|
|
81
82
|
|
|
@@ -83,7 +84,7 @@ Benchmark.bm(70) do |bm|
|
|
|
83
84
|
bm.report("Querying & Iterating #{posts_size} Posts with #{comments_size} Comments and #{users_size} Users") do
|
|
84
85
|
10.times do
|
|
85
86
|
Bullet.start_request
|
|
86
|
-
Post.select(
|
|
87
|
+
Post.select('SQL_NO_CACHE *').includes(:user, comments: :user).each do |p|
|
|
87
88
|
p.title
|
|
88
89
|
p.user.name
|
|
89
90
|
p.comments.each do |c|
|
|
@@ -96,8 +97,7 @@ Benchmark.bm(70) do |bm|
|
|
|
96
97
|
end
|
|
97
98
|
end
|
|
98
99
|
|
|
99
|
-
puts
|
|
100
|
-
|
|
100
|
+
puts 'End benchmarking...'
|
|
101
101
|
|
|
102
102
|
# Run benchmark with bundler
|
|
103
103
|
#
|
data/rails/init.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
module Bullet
|
|
@@ -8,15 +10,15 @@ module Bullet
|
|
|
8
10
|
@post2 = Post.last
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
context
|
|
12
|
-
it
|
|
13
|
+
context '.add_object_association' do
|
|
14
|
+
it 'should add object, associations pair' do
|
|
13
15
|
Association.add_object_associations(@post1, :associations)
|
|
14
16
|
expect(Association.send(:object_associations)).to be_include(@post1.bullet_key, :associations)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
context
|
|
19
|
-
it
|
|
20
|
+
context '.add_call_object_associations' do
|
|
21
|
+
it 'should add call object, associations pair' do
|
|
20
22
|
Association.add_call_object_associations(@post1, :associations)
|
|
21
23
|
expect(Association.send(:call_object_associations)).to be_include(@post1.bullet_key, :associations)
|
|
22
24
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
module Bullet
|
|
@@ -8,44 +10,44 @@ module Bullet
|
|
|
8
10
|
@post2 = Post.last
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
context
|
|
12
|
-
it
|
|
13
|
+
context '.add_counter_cache' do
|
|
14
|
+
it 'should create notification if conditions met' do
|
|
13
15
|
expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(true)
|
|
14
|
-
expect(CounterCache).to receive(:create_notification).with(
|
|
16
|
+
expect(CounterCache).to receive(:create_notification).with('Post', [:comments])
|
|
15
17
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
16
18
|
end
|
|
17
19
|
|
|
18
|
-
it
|
|
20
|
+
it 'should not create notification if conditions not met' do
|
|
19
21
|
expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(false)
|
|
20
22
|
expect(CounterCache).to receive(:create_notification).never
|
|
21
23
|
CounterCache.add_counter_cache(@post1, [:comments])
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
context
|
|
26
|
-
it
|
|
27
|
+
context '.add_possible_objects' do
|
|
28
|
+
it 'should add possible objects' do
|
|
27
29
|
CounterCache.add_possible_objects([@post1, @post2])
|
|
28
30
|
expect(CounterCache.possible_objects).to be_include(@post1.bullet_key)
|
|
29
31
|
expect(CounterCache.possible_objects).to be_include(@post2.bullet_key)
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
it
|
|
34
|
+
it 'should add impossible object' do
|
|
33
35
|
CounterCache.add_impossible_object(@post1)
|
|
34
36
|
expect(CounterCache.impossible_objects).to be_include(@post1.bullet_key)
|
|
35
37
|
end
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
context
|
|
39
|
-
it
|
|
40
|
+
context '.conditions_met?' do
|
|
41
|
+
it 'should be true when object is possible, not impossible' do
|
|
40
42
|
CounterCache.add_possible_objects(@post1)
|
|
41
43
|
expect(CounterCache.conditions_met?(@post1, :associations)).to eq true
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
it
|
|
46
|
+
it 'should be false when object is not possible' do
|
|
45
47
|
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
it
|
|
50
|
+
it 'should be true when object is possible, and impossible' do
|
|
49
51
|
CounterCache.add_possible_objects(@post1)
|
|
50
52
|
CounterCache.add_impossible_object(@post1)
|
|
51
53
|
expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
|