bullet 4.8.0 → 4.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +1 -1
- data/Gemfile.rails-3.2 +1 -1
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +8 -1
- data/README.md +4 -1
- data/bullet.gemspec +1 -1
- data/lib/bullet.rb +7 -3
- data/lib/bullet/active_record3x.rb +1 -1
- data/lib/bullet/active_record4.rb +1 -1
- data/lib/bullet/active_record41.rb +1 -1
- data/lib/bullet/detector/n_plus_one_query.rb +4 -1
- data/lib/bullet/notification/base.rb +11 -2
- data/lib/bullet/notification/n_plus_one_query.rb +1 -1
- data/lib/bullet/version.rb +1 -1
- data/spec/bullet/detector/n_plus_one_query_spec.rb +28 -0
- data/spec/bullet/notification/base_spec.rb +14 -4
- data/spec/bullet/notification/n_plus_one_query_spec.rb +1 -0
- data/spec/spec_helper.rb +4 -4
- data/spec/support/sqlite_seed.rb +0 -6
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5d5793126ed37cd4f560144b157258999c0b318
|
4
|
+
data.tar.gz: 56e7d6b4a5d4a2fda7bcc9707523e4863159aa83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 817982d863e94c8fb85379b07006536e83c4ea97e0b92a9f7cc4a1444dcba2f4743202a25a9a6f68b9be2cad20985bd6fb5c0a45a4015a93e782ac4eaaa95da9
|
7
|
+
data.tar.gz: 14311a13bfd4b6bcd88f2f72271b3e39a681ee19c13d42aeba4318a7826e4e927792479b75f6d07357725699dd6d0a0d7b6c2545e3f37ed4d24fb86766d10b20
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.rails-3.2
CHANGED
data/Gemfile.rails-4.0
CHANGED
data/Gemfile.rails-4.1
CHANGED
@@ -2,9 +2,11 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem 'rails', '4.1.0
|
5
|
+
gem 'rails', '~> 4.1.0'
|
6
6
|
gem 'sqlite3'
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
7
8
|
gem 'mysql2'
|
9
|
+
gem 'activerecord-jdbcmysql-adapter', platforms: [:jruby]
|
8
10
|
gem 'activerecord-import'
|
9
11
|
|
10
12
|
gem "rspec"
|
@@ -12,3 +14,8 @@ gem "guard"
|
|
12
14
|
gem "guard-rspec"
|
13
15
|
|
14
16
|
gem 'coveralls', require: false
|
17
|
+
|
18
|
+
platforms :rbx do
|
19
|
+
gem 'rubysl', '~> 2.0'
|
20
|
+
gem 'rubinius-developer_tools'
|
21
|
+
end
|
data/README.md
CHANGED
@@ -53,8 +53,10 @@ config.after_initialize do
|
|
53
53
|
:receiver => 'your_account@jabber.org',
|
54
54
|
:show_online_status => true }
|
55
55
|
Bullet.rails_logger = true
|
56
|
+
Bullet.bugsnag = true
|
56
57
|
Bullet.airbrake = true
|
57
58
|
Bullet.add_footer = true
|
59
|
+
Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
|
58
60
|
end
|
59
61
|
```
|
60
62
|
|
@@ -71,9 +73,10 @@ The code above will enable all seven of the Bullet notification systems:
|
|
71
73
|
* `Bullet.xmpp`: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the bullet account may start to annoy - in this case set :show_online_status to false; you will still get notifications, but the bullet account won't announce it's online status anymore.
|
72
74
|
* `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
|
73
75
|
* `Bullet.add_footer`: adds the details in the bottom left corner of the page
|
76
|
+
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
74
77
|
|
75
78
|
Bullet also allows you to disable n_plus_one_query, unused_eager_loading
|
76
|
-
and counter_cache detectors respectively
|
79
|
+
and counter_cache detectors respectively.
|
77
80
|
|
78
81
|
```ruby
|
79
82
|
Bullet.n_plus_one_query_enable = false
|
data/bullet.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.required_rubygems_version = ">= 1.3.6"
|
17
17
|
|
18
18
|
s.add_dependency "activesupport"
|
19
|
-
s.add_dependency "uniform_notifier", "
|
19
|
+
s.add_dependency "uniform_notifier", "~> 1.6.0"
|
20
20
|
|
21
21
|
s.files = `git ls-files`.split("\n")
|
22
22
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/bullet.rb
CHANGED
@@ -25,11 +25,11 @@ module Bullet
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class << self
|
28
|
-
attr_writer :enable, :n_plus_one_query_enable, :unused_eager_loading_enable, :counter_cache_enable
|
28
|
+
attr_writer :enable, :n_plus_one_query_enable, :unused_eager_loading_enable, :counter_cache_enable, :stacktrace_includes
|
29
29
|
attr_reader :notification_collector, :whitelist
|
30
30
|
attr_accessor :add_footer
|
31
31
|
|
32
|
-
delegate :alert=, :console=, :growl=, :rails_logger=, :xmpp=, :airbrake=, :to => UniformNotifier
|
32
|
+
delegate :alert=, :console=, :growl=, :rails_logger=, :xmpp=, :airbrake=, :bugsnag=, :to => UniformNotifier
|
33
33
|
|
34
34
|
def raise=(should_raise)
|
35
35
|
UniformNotifier.raise=(should_raise ? Notification::UnoptimizedQueryError : false)
|
@@ -64,9 +64,13 @@ module Bullet
|
|
64
64
|
self.enable? && !!@counter_cache_enable
|
65
65
|
end
|
66
66
|
|
67
|
+
def stacktrace_includes
|
68
|
+
@stacktrace_includes || []
|
69
|
+
end
|
70
|
+
|
67
71
|
def add_whitelist(options)
|
68
72
|
@whitelist[options[:type]][options[:class_name].classify] ||= []
|
69
|
-
@whitelist[options[:type]][options[:class_name].classify] << options[:association]
|
73
|
+
@whitelist[options[:type]][options[:class_name].classify] << options[:association].to_sym
|
70
74
|
end
|
71
75
|
|
72
76
|
def get_whitelist_associations(type, class_name)
|
@@ -93,7 +93,7 @@ module Bullet
|
|
93
93
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
94
94
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
95
95
|
|
96
|
-
def has_cached_counter?(reflection = reflection)
|
96
|
+
def has_cached_counter?(reflection = reflection())
|
97
97
|
result = origin_has_cached_counter?(reflection)
|
98
98
|
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) unless result
|
99
99
|
result
|
@@ -93,7 +93,7 @@ module Bullet
|
|
93
93
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
94
94
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
95
95
|
|
96
|
-
def has_cached_counter?(reflection = reflection)
|
96
|
+
def has_cached_counter?(reflection = reflection())
|
97
97
|
result = origin_has_cached_counter?(reflection)
|
98
98
|
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) unless result
|
99
99
|
result
|
@@ -86,7 +86,7 @@ module Bullet
|
|
86
86
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
87
87
|
alias_method :origin_has_cached_counter?, :has_cached_counter?
|
88
88
|
|
89
|
-
def has_cached_counter?(reflection = reflection)
|
89
|
+
def has_cached_counter?(reflection = reflection())
|
90
90
|
result = origin_has_cached_counter?(reflection)
|
91
91
|
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name) unless result
|
92
92
|
result
|
@@ -50,7 +50,10 @@ module Bullet
|
|
50
50
|
def caller_in_project
|
51
51
|
app_root = rails? ? Rails.root.to_s : Dir.pwd
|
52
52
|
vendor_root = app_root + "/vendor"
|
53
|
-
caller.select
|
53
|
+
caller.select do |c|
|
54
|
+
c.include?(app_root) && !c.include?(vendor_root) ||
|
55
|
+
Bullet.stacktrace_includes.any? { |include| c.include?(include) }
|
56
|
+
end
|
54
57
|
end
|
55
58
|
|
56
59
|
def possible?(bullet_ar_key)
|
@@ -40,17 +40,26 @@ module Bullet
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def notify_inline
|
43
|
-
self.notifier.inline_notify(
|
43
|
+
self.notifier.inline_notify(notification_data)
|
44
44
|
end
|
45
45
|
|
46
46
|
def notify_out_of_channel
|
47
|
-
self.notifier.out_of_channel_notify(
|
47
|
+
self.notifier.out_of_channel_notify(notification_data)
|
48
48
|
end
|
49
49
|
|
50
50
|
def short_notice
|
51
51
|
[whoami, url, title, body].compact.join("\n")
|
52
52
|
end
|
53
53
|
|
54
|
+
def notification_data
|
55
|
+
{
|
56
|
+
:user => whoami,
|
57
|
+
:url => url,
|
58
|
+
:title => title,
|
59
|
+
:body => body_with_caller,
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
54
63
|
def eql?(other)
|
55
64
|
klazz_associations_str == other.klazz_associations_str
|
56
65
|
end
|
data/lib/bullet/version.rb
CHANGED
@@ -93,6 +93,34 @@ module Bullet
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
+
context ".caller_in_project" do
|
97
|
+
it "should include only paths that are in the project" do
|
98
|
+
in_project = File.join(Dir.pwd, 'abc', 'abc.rb')
|
99
|
+
not_in_project = '/def/def.rb'
|
100
|
+
|
101
|
+
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, not_in_project])
|
102
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_ar_key, :association).and_return(true)
|
103
|
+
expect(NPlusOneQuery).to receive(:create_notification).with([in_project], "Post", :association)
|
104
|
+
NPlusOneQuery.call_association(@post, :association)
|
105
|
+
end
|
106
|
+
|
107
|
+
context "stacktrace_includes" do
|
108
|
+
before { Bullet.stacktrace_includes = [ 'def' ] }
|
109
|
+
after { Bullet.stacktrace_includes = nil }
|
110
|
+
|
111
|
+
it "should include paths that are in the stacktrace_include list" do
|
112
|
+
in_project = File.join(Dir.pwd, 'abc', 'abc.rb')
|
113
|
+
included_gem = '/def/def.rb'
|
114
|
+
excluded_gem = '/ghi/ghi.rb'
|
115
|
+
|
116
|
+
expect(NPlusOneQuery).to receive(:caller).and_return([in_project, included_gem, excluded_gem])
|
117
|
+
expect(NPlusOneQuery).to receive(:conditions_met?).with(@post.bullet_ar_key, :association).and_return(true)
|
118
|
+
expect(NPlusOneQuery).to receive(:create_notification).with([in_project, included_gem], "Post", :association)
|
119
|
+
NPlusOneQuery.call_association(@post, :association)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
96
124
|
context ".add_possible_objects" do
|
97
125
|
it "should add possible objects" do
|
98
126
|
NPlusOneQuery.add_possible_objects([@post, @post2])
|
@@ -49,12 +49,22 @@ module Bullet
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
context "#notification_data" do
|
53
|
+
it "should return notification data" do
|
54
|
+
allow(subject).to receive(:whoami).and_return("whoami")
|
55
|
+
allow(subject).to receive(:url).and_return("url")
|
56
|
+
allow(subject).to receive(:title).and_return("title")
|
57
|
+
allow(subject).to receive(:body_with_caller).and_return("body_with_caller")
|
58
|
+
expect(subject.notification_data).to eq(:user => "whoami", :url => "url", :title => "title", :body => "body_with_caller")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
52
62
|
context "#notify_inline" do
|
53
63
|
it "should send full_notice to notifier" do
|
54
64
|
notifier = double
|
55
65
|
allow(subject).to receive(:notifier).and_return(notifier)
|
56
|
-
allow(subject).to receive(:
|
57
|
-
expect(notifier).to receive(:inline_notify).with(
|
66
|
+
allow(subject).to receive(:notification_data).and_return(:foo => :bar)
|
67
|
+
expect(notifier).to receive(:inline_notify).with(:foo => :bar)
|
58
68
|
subject.notify_inline
|
59
69
|
end
|
60
70
|
end
|
@@ -63,8 +73,8 @@ module Bullet
|
|
63
73
|
it "should send full_out_of_channel to notifier" do
|
64
74
|
notifier = double
|
65
75
|
allow(subject).to receive(:notifier).and_return(notifier)
|
66
|
-
allow(subject).to receive(:
|
67
|
-
expect(notifier).to receive(:out_of_channel_notify).with(
|
76
|
+
allow(subject).to receive(:notification_data).and_return(:foo => :bar)
|
77
|
+
expect(notifier).to receive(:out_of_channel_notify).with(:foo => :bar)
|
68
78
|
subject.notify_out_of_channel
|
69
79
|
end
|
70
80
|
end
|
@@ -6,6 +6,7 @@ module Bullet
|
|
6
6
|
subject { NPlusOneQuery.new([["caller1", "caller2"]], Post, [:comments, :votes], "path") }
|
7
7
|
|
8
8
|
it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :include => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2") }
|
9
|
+
it { expect([ subject.body_with_caller, subject.body_with_caller]).to eq([ " Post => [:comments, :votes]\n Add to your finder: :include => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2", " Post => [:comments, :votes]\n Add to your finder: :include => [:comments, :votes]\nN+1 Query method call stack\n caller1\n caller2" ]) }
|
9
10
|
it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your finder: :include => [:comments, :votes]") }
|
10
11
|
it { expect(subject.title).to eq("N+1 Query in path") }
|
11
12
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,6 +13,10 @@ module Rails
|
|
13
13
|
def root
|
14
14
|
File.expand_path(__FILE__).split('/')[0..-3].join('/')
|
15
15
|
end
|
16
|
+
|
17
|
+
def env
|
18
|
+
"test"
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
22
|
|
@@ -51,10 +55,6 @@ if active_record?
|
|
51
55
|
Support::SqliteSeed.setup_db
|
52
56
|
Support::SqliteSeed.seed_db
|
53
57
|
end
|
54
|
-
|
55
|
-
config.after(:suite) do
|
56
|
-
Support::SqliteSeed.teardown_db
|
57
|
-
end
|
58
58
|
end
|
59
59
|
|
60
60
|
if ENV["LOG"]
|
data/spec/support/sqlite_seed.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: uniform_notifier
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.6.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.6.0
|
41
41
|
description: help to kill N+1 queries and unused eager loading.
|
42
42
|
email:
|
43
43
|
- flyerhzm@gmail.com
|
@@ -177,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
177
|
version: 1.3.6
|
178
178
|
requirements: []
|
179
179
|
rubyforge_project:
|
180
|
-
rubygems_version: 2.2.
|
180
|
+
rubygems_version: 2.2.2
|
181
181
|
signing_key:
|
182
182
|
specification_version: 4
|
183
183
|
summary: help to kill N+1 queries and unused eager loading.
|