bullet 2.2.0 → 2.3.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.
Files changed (81) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +4 -1
  3. data/Gemfile +3 -2
  4. data/Gemfile.lock +85 -69
  5. data/Guardfile +8 -0
  6. data/README.textile +2 -2
  7. data/lib/bullet/action_controller2.rb +4 -4
  8. data/lib/bullet/active_record2.rb +5 -6
  9. data/lib/bullet/active_record3.rb +2 -3
  10. data/lib/bullet/active_record31.rb +10 -12
  11. data/lib/bullet/detector/association.rb +27 -53
  12. data/lib/bullet/detector/counter.rb +34 -29
  13. data/lib/bullet/detector/n_plus_one_query.rb +47 -28
  14. data/lib/bullet/detector/unused_eager_association.rb +31 -30
  15. data/lib/bullet/notification/base.rb +14 -12
  16. data/lib/bullet/notification/n_plus_one_query.rb +6 -10
  17. data/lib/bullet/notification/unused_eager_loading.rb +1 -2
  18. data/lib/bullet/notification_collector.rb +1 -2
  19. data/lib/bullet/rack.rb +6 -3
  20. data/lib/bullet/registry/association.rb +4 -6
  21. data/lib/bullet/registry/base.rb +10 -7
  22. data/lib/bullet/registry/object.rb +6 -6
  23. data/lib/bullet/version.rb +1 -1
  24. data/lib/bullet.rb +13 -8
  25. data/perf/benchmark.rb +30 -12
  26. data/spec/bullet/detector/association_spec.rb +90 -0
  27. data/spec/bullet/detector/base_spec.rb +14 -0
  28. data/spec/bullet/detector/counter_spec.rb +65 -0
  29. data/spec/bullet/detector/n_plus_one_query_spec.rb +94 -0
  30. data/spec/bullet/detector/unused_eager_association_spec.rb +62 -0
  31. data/spec/bullet/notification/base_spec.rb +67 -0
  32. data/spec/bullet/notification/counter_cache_spec.rb +12 -0
  33. data/spec/bullet/notification/n_plus_one_query_spec.rb +13 -0
  34. data/spec/bullet/notification/unused_eager_loading_spec.rb +12 -0
  35. data/spec/bullet/notification_collector_spec.rb +32 -0
  36. data/spec/bullet/rack_spec.rb +80 -24
  37. data/spec/bullet/registry/association_spec.rb +26 -0
  38. data/spec/bullet/registry/base_spec.rb +44 -0
  39. data/spec/bullet/registry/object_spec.rb +25 -0
  40. data/spec/integration/association_for_chris_spec.rb +37 -0
  41. data/spec/integration/association_for_peschkaj_spec.rb +26 -0
  42. data/spec/{bullet → integration}/association_spec.rb +1 -359
  43. data/spec/integration/counter_spec.rb +37 -0
  44. data/spec/models/address.rb +3 -0
  45. data/spec/models/author.rb +3 -0
  46. data/spec/models/base_user.rb +5 -0
  47. data/spec/models/category.rb +7 -0
  48. data/spec/models/city.rb +3 -0
  49. data/spec/models/client.rb +4 -0
  50. data/spec/models/comment.rb +4 -0
  51. data/spec/models/company.rb +3 -0
  52. data/spec/models/contact.rb +3 -0
  53. data/spec/models/country.rb +3 -0
  54. data/spec/models/deal.rb +4 -0
  55. data/spec/models/document.rb +5 -0
  56. data/spec/models/email.rb +3 -0
  57. data/spec/models/entry.rb +3 -0
  58. data/spec/models/firm.rb +4 -0
  59. data/spec/models/folder.rb +2 -0
  60. data/spec/models/hotel.rb +4 -0
  61. data/spec/models/location.rb +3 -0
  62. data/spec/models/newspaper.rb +3 -0
  63. data/spec/models/page.rb +2 -0
  64. data/spec/models/person.rb +3 -0
  65. data/spec/models/pet.rb +3 -0
  66. data/spec/models/post.rb +11 -0
  67. data/spec/models/relationship.rb +4 -0
  68. data/spec/models/student.rb +3 -0
  69. data/spec/models/submission.rb +4 -0
  70. data/spec/models/teacher.rb +3 -0
  71. data/spec/models/user.rb +4 -0
  72. data/spec/models/writer.rb +2 -0
  73. data/spec/spec_helper.rb +16 -106
  74. data/spec/support/bullet_ext.rb +55 -0
  75. data/spec/support/rack_double.rb +55 -0
  76. data/spec/support/seed.rb +256 -0
  77. metadata +104 -14
  78. data/.watchr +0 -24
  79. data/spec/bullet/association_for_chris_spec.rb +0 -96
  80. data/spec/bullet/association_for_peschkaj_spec.rb +0 -86
  81. data/spec/bullet/counter_spec.rb +0 -136
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'pry'
2
- require 'rubygems'
3
1
  require 'rspec'
4
2
  require 'rspec/autorun'
5
3
  require 'rails'
@@ -19,116 +17,28 @@ require 'bullet'
19
17
  Bullet.enable = true
20
18
  ActiveRecord::Migration.verbose = false
21
19
 
22
- module Bullet
23
- def self.collected_notifications_of_class( notification_class )
24
- Bullet.notification_collector.collection.select do |notification|
25
- notification.is_a? notification_class
26
- end
27
- end
28
-
29
- def self.collected_counter_cache_notifications
30
- collected_notifications_of_class Bullet::Notification::CounterCache
31
- end
32
-
33
- def self.collected_n_plus_one_query_notifications
34
- collected_notifications_of_class Bullet::Notification::NPlusOneQuery
35
- end
36
-
37
- def self.collected_unused_eager_association_notifications
38
- collected_notifications_of_class Bullet::Notification::UnusedEagerLoading
39
- end
40
- end
41
-
42
- module Bullet
43
- module Detector
44
- class Association
45
- class <<self
46
- # returns true if all associations are preloaded
47
- def completely_preloading_associations?
48
- Bullet.collected_n_plus_one_query_notifications.empty?
49
- end
50
-
51
- def has_unused_preload_associations?
52
- Bullet.collected_unused_eager_association_notifications.present?
53
- end
54
-
55
- # returns true if a given object has a specific association
56
- def creating_object_association_for?(object, association)
57
- object_associations[object].present? && object_associations[object].include?(association)
58
- end
59
-
60
- # returns true if a given class includes the specific unpreloaded association
61
- def detecting_unpreloaded_association_for?(klass, association)
62
- for_class_and_assoc = Bullet.collected_n_plus_one_query_notifications.select do |notification|
63
- notification.base_class == klass and
64
- notification.associations.include?( association )
65
- end
66
- for_class_and_assoc.present?
67
- end
68
-
69
- # returns true if the given class includes the specific unused preloaded association
70
- def unused_preload_associations_for?(klass, association)
71
- for_class_and_assoc = Bullet.collected_unused_eager_association_notifications.select do |notification|
72
- notification.base_class == klass and
73
- notification.associations.include?( association )
74
- end
75
- for_class_and_assoc.present?
76
- end
77
- end
78
- end
79
- end
80
- end
20
+ MODELS = File.join(File.dirname(__FILE__), "models")
21
+ $LOAD_PATH.unshift(MODELS)
81
22
 
82
- class AppDouble
83
- def call env
84
- env = @env
85
- [ status, headers, response ]
86
- end
87
-
88
- def status= status
89
- @status = status
90
- end
91
-
92
- def headers= headers
93
- @headers = headers
94
- end
95
-
96
- def headers
97
- @headers ||= {}
98
- @headers
99
- end
100
-
101
- def response= response
102
- @response = response
103
- end
104
-
105
- private
106
- def status
107
- @status || 200
108
- end
109
-
110
- def response
111
- @response || ResponseDouble.new
112
- end
23
+ # Autoload every model for the test suite that sits in spec/models.
24
+ Dir[ File.join(MODELS, "*.rb") ].sort.each do |file|
25
+ name = File.basename(file, ".rb")
26
+ autoload name.camelize.to_sym, name
113
27
  end
114
28
 
115
- class ResponseDouble
116
- def initialize actual_body = nil
117
- @actual_body = actual_body
118
- end
119
-
120
- def body
121
- @body ||= "Hello world!"
122
- end
29
+ SUPPORT = File.join(File.dirname(__FILE__), "support")
30
+ Dir[ File.join(SUPPORT, "*.rb") ].sort.each { |file| require file }
123
31
 
124
- def body= body
125
- @body = body
32
+ RSpec.configure do |config|
33
+ config.before(:suite) do
34
+ Support::Seed.setup_db
35
+ Support::Seed.seed_db
126
36
  end
127
37
 
128
- def each
129
- yield body
38
+ config.after(:suite) do
39
+ Support::Seed.teardown_db
130
40
  end
131
41
 
132
- def close
133
- end
42
+ config.filter_run :focus => true
43
+ config.run_all_when_everything_filtered = true
134
44
  end
@@ -0,0 +1,55 @@
1
+ module Bullet
2
+ def self.collected_notifications_of_class(notification_class)
3
+ Bullet.notification_collector.collection.select do |notification|
4
+ notification.is_a? notification_class
5
+ end
6
+ end
7
+
8
+ def self.collected_counter_cache_notifications
9
+ collected_notifications_of_class Bullet::Notification::CounterCache
10
+ end
11
+
12
+ def self.collected_n_plus_one_query_notifications
13
+ collected_notifications_of_class Bullet::Notification::NPlusOneQuery
14
+ end
15
+
16
+ def self.collected_unused_eager_association_notifications
17
+ collected_notifications_of_class Bullet::Notification::UnusedEagerLoading
18
+ end
19
+ end
20
+
21
+ module Bullet
22
+ module Detector
23
+ class Association
24
+ class <<self
25
+ # returns true if all associations are preloaded
26
+ def completely_preloading_associations?
27
+ Bullet.collected_n_plus_one_query_notifications.empty?
28
+ end
29
+
30
+ def has_unused_preload_associations?
31
+ Bullet.collected_unused_eager_association_notifications.present?
32
+ end
33
+
34
+ # returns true if a given object has a specific association
35
+ def creating_object_association_for?(object, association)
36
+ object_associations[object.ar_key].present? && object_associations[object.ar_key].include?(association)
37
+ end
38
+
39
+ # returns true if a given class includes the specific unpreloaded association
40
+ def detecting_unpreloaded_association_for?(klass, association)
41
+ Bullet.collected_n_plus_one_query_notifications.select { |notification|
42
+ notification.base_class == klass.to_s && notification.associations.include?(association)
43
+ }.present?
44
+ end
45
+
46
+ # returns true if the given class includes the specific unused preloaded association
47
+ def unused_preload_associations_for?(klass, association)
48
+ Bullet.collected_unused_eager_association_notifications.select { |notification|
49
+ notification.base_class == klass.to_s && notification.associations.include?(association)
50
+ }.present?
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,55 @@
1
+ module Support
2
+ class AppDouble
3
+ def call env
4
+ env = @env
5
+ [ status, headers, response ]
6
+ end
7
+
8
+ def status= status
9
+ @status = status
10
+ end
11
+
12
+ def headers= headers
13
+ @headers = headers
14
+ end
15
+
16
+ def headers
17
+ @headers ||= {"Content-Type" => "text/html"}
18
+ @headers
19
+ end
20
+
21
+ def response= response
22
+ @response = response
23
+ end
24
+
25
+ private
26
+ def status
27
+ @status || 200
28
+ end
29
+
30
+ def response
31
+ @response || ResponseDouble.new
32
+ end
33
+ end
34
+
35
+ class ResponseDouble
36
+ def initialize actual_body = nil
37
+ @actual_body = actual_body
38
+ end
39
+
40
+ def body
41
+ @body ||= "<html><head></head><body></body></html>"
42
+ end
43
+
44
+ def body= body
45
+ @body = body
46
+ end
47
+
48
+ def each
49
+ yield body
50
+ end
51
+
52
+ def close
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,256 @@
1
+ module Support
2
+ module Seed
3
+ def seed_db
4
+ newspaper1 = Newspaper.create(:name => "First Newspaper")
5
+ newspaper2 = Newspaper.create(:name => "Second Newspaper")
6
+
7
+ writer1 = Writer.create(:name => 'first', :newspaper => newspaper1)
8
+ writer2 = Writer.create(:name => 'second', :newspaper => newspaper2)
9
+ user1 = BaseUser.create(:name => 'third', :newspaper => newspaper1)
10
+ user2 = BaseUser.create(:name => 'fourth', :newspaper => newspaper2)
11
+
12
+
13
+ category1 = Category.create(:name => 'first')
14
+ category2 = Category.create(:name => 'second')
15
+
16
+ post1 = category1.posts.create(:name => 'first', :writer => writer1)
17
+ post1a = category1.posts.create(:name => 'like first', :writer => writer2)
18
+ post2 = category2.posts.create(:name => 'second', :writer => writer2)
19
+
20
+ comment1 = post1.comments.create(:name => 'first', :author => writer1)
21
+ comment2 = post1.comments.create(:name => 'first2', :author => writer1)
22
+ comment3 = post1.comments.create(:name => 'first3', :author => writer1)
23
+ comment4 = post1.comments.create(:name => 'second', :author => writer2)
24
+ comment8 = post1a.comments.create(:name => "like first 1", :author => writer1)
25
+ comment9 = post1a.comments.create(:name => "like first 2", :author => writer2)
26
+ comment5 = post2.comments.create(:name => 'third', :author => user1)
27
+ comment6 = post2.comments.create(:name => 'fourth', :author => user2)
28
+ comment7 = post2.comments.create(:name => 'fourth', :author => writer1)
29
+
30
+ entry1 = category1.entries.create(:name => 'first')
31
+ entry2 = category1.entries.create(:name => 'second')
32
+
33
+ student1 = Student.create(:name => 'first')
34
+ student2 = Student.create(:name => 'second')
35
+ teacher1 = Teacher.create(:name => 'first')
36
+ teacher2 = Teacher.create(:name => 'second')
37
+ student1.teachers = [teacher1, teacher2]
38
+ student2.teachers = [teacher1, teacher2]
39
+ teacher1.students << student1
40
+ teacher2.students << student2
41
+
42
+ firm1 = Firm.create(:name => 'first')
43
+ firm2 = Firm.create(:name => 'second')
44
+ client1 = Client.create(:name => 'first')
45
+ client2 = Client.create(:name => 'second')
46
+ firm1.clients = [client1, client2]
47
+ firm2.clients = [client1, client2]
48
+ client1.firms << firm1
49
+ client2.firms << firm2
50
+
51
+ company1 = Company.create(:name => 'first')
52
+ company2 = Company.create(:name => 'second')
53
+
54
+ Address.create(:name => 'first', :company => company1)
55
+ Address.create(:name => 'second', :company => company2)
56
+
57
+ contact1 = Contact.create(:name => 'first')
58
+ contact2 = Contact.create(:name => 'second')
59
+
60
+ email1 = contact1.emails.create(:name => 'first')
61
+ email2 = contact1.emails.create(:name => 'second')
62
+ email3 = contact2.emails.create(:name => 'third')
63
+ email4 = contact2.emails.create(:name => 'fourth')
64
+
65
+ country1 = Country.create(:name => 'first')
66
+ country2 = Country.create(:name => 'second')
67
+
68
+ country1.cities.create(:name => 'first')
69
+ country1.cities.create(:name => 'second')
70
+ country2.cities.create(:name => 'third')
71
+ country2.cities.create(:name => 'fourth')
72
+
73
+ person1 = Person.create(:name => 'first')
74
+ person2 = Person.create(:name => 'second')
75
+
76
+ person1.pets.create(:name => 'first')
77
+ person1.pets.create(:name => 'second')
78
+ person2.pets.create(:name => 'third')
79
+ person2.pets.create(:name => 'fourth')
80
+
81
+ author1 = Author.create(:name => 'author1')
82
+ author2 = Author.create(:name => 'author2')
83
+ folder1 = Folder.create(:name => 'folder1', :author_id => author1.id)
84
+ folder2 = Folder.create(:name => 'folder2', :author_id => author2.id)
85
+ page1 = Page.create(:name => 'page1', :parent_id => folder1.id, :author_id => author1.id)
86
+ page2 = Page.create(:name => 'page2', :parent_id => folder1.id, :author_id => author1.id)
87
+ page3 = Page.create(:name => 'page3', :parent_id => folder2.id, :author_id => author2.id)
88
+ page4 = Page.create(:name => 'page4', :parent_id => folder2.id, :author_id => author2.id)
89
+
90
+ user1 = User.create(:name => 'user1', :category => category1)
91
+ user2 = User.create(:name => 'user2', :category => category1)
92
+
93
+ submission1 = category1.submissions.create(:name => "submission1", :user => user1)
94
+ submission2 = category1.submissions.create(:name => "submission2", :user => user2)
95
+ submission3 = category2.submissions.create(:name => "submission3", :user => user1)
96
+ submission4 = category2.submissions.create(:name => "submission4", :user => user2)
97
+
98
+ location1 = Location.create(:name => "location1")
99
+ location2 = Location.create(:name => "location2")
100
+
101
+ hotel1 = location1.hotels.create(:name => "hotel1")
102
+ hotel2 = location1.hotels.create(:name => "hotel2")
103
+ hotel3 = location2.hotels.create(:name => "hotel3")
104
+ hotel4 = location2.hotels.create(:name => "hotel4")
105
+
106
+ deal1 = hotel1.deals.create(:name => "deal1")
107
+ deal2 = hotel2.deals.create(:name => "deal2")
108
+ deal3 = hotel3.deals.create(:name => "deal3")
109
+ deal4 = hotel4.deals.create(:name => "deal4")
110
+ end
111
+
112
+ def setup_db
113
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
114
+
115
+ ActiveRecord::Schema.define(:version => 1) do
116
+ create_table :addresses do |t|
117
+ t.column :name, :string
118
+ t.column :company_id, :integer
119
+ end
120
+
121
+ create_table :authors do |t|
122
+ t.string :name
123
+ end
124
+
125
+ create_table :base_users do |t|
126
+ t.column :name, :string
127
+ t.column :type, :string
128
+ t.column :newspaper_id, :integer
129
+ end
130
+
131
+ create_table :categories do |t|
132
+ t.column :name, :string
133
+ end
134
+
135
+ create_table :cities do |t|
136
+ t.string :name
137
+ t.integer :country_id
138
+ end
139
+
140
+ create_table :clients do |t|
141
+ t.column :name, :string
142
+ end
143
+
144
+ create_table :comments do |t|
145
+ t.column :name, :string
146
+ t.column :post_id, :integer
147
+ t.column :author_id, :integer
148
+ end
149
+
150
+ create_table :companies do |t|
151
+ t.column :name, :string
152
+ end
153
+
154
+ create_table :contacts do |t|
155
+ t.column :name, :string
156
+ end
157
+
158
+ create_table :countries do |t|
159
+ t.string :name
160
+ end
161
+
162
+ create_table :deals do |t|
163
+ t.column :name, :string
164
+ t.column :hotel_id, :integer
165
+ end
166
+
167
+ create_table :documents do |t|
168
+ t.string :name
169
+ t.string :type
170
+ t.integer :parent_id
171
+ t.integer :author_id
172
+ end
173
+
174
+ create_table :emails do |t|
175
+ t.column :name, :string
176
+ t.column :contact_id, :integer
177
+ end
178
+
179
+ create_table :entries do |t|
180
+ t.column :name, :string
181
+ t.column :category_id, :integer
182
+ end
183
+
184
+ create_table :firms do |t|
185
+ t.column :name, :string
186
+ end
187
+
188
+ create_table :hotels do |t|
189
+ t.column :name, :string
190
+ t.column :location_id, :integer
191
+ end
192
+
193
+ create_table :locations do |t|
194
+ t.column :name, :string
195
+ end
196
+
197
+ create_table :newspapers do |t|
198
+ t.column :name, :string
199
+ end
200
+
201
+ create_table :people do |t|
202
+ t.string :name
203
+ t.integer :pets_count
204
+ end
205
+
206
+ create_table :pets do |t|
207
+ t.string :name
208
+ t.integer :person_id
209
+ end
210
+
211
+ create_table :posts do |t|
212
+ t.column :name, :string
213
+ t.column :category_id, :integer
214
+ t.column :writer_id, :integer
215
+ end
216
+
217
+ create_table :relationships do |t|
218
+ t.column :firm_id, :integer
219
+ t.column :client_id, :integer
220
+ end
221
+
222
+ create_table :students do |t|
223
+ t.column :name, :string
224
+ end
225
+
226
+ create_table :students_teachers, :id => false do |t|
227
+ t.column :student_id, :integer
228
+ t.column :teacher_id, :integer
229
+ end
230
+
231
+ create_table :teachers do |t|
232
+ t.column :name, :string
233
+ end
234
+
235
+ create_table :submissions do |t|
236
+ t.column :name, :string
237
+ t.column :category_id, :integer
238
+ t.column :user_id, :integer
239
+ end
240
+
241
+ create_table :users do |t|
242
+ t.column :name, :string
243
+ t.column :category_id, :integer
244
+ end
245
+ end
246
+ end
247
+
248
+ def teardown_db
249
+ ActiveRecord::Base.connection.tables.each do |table|
250
+ ActiveRecord::Base.connection.drop_table(table)
251
+ end
252
+ end
253
+
254
+ extend self
255
+ end
256
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bullet
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-05 00:00:00.000000000 Z
12
+ date: 2012-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: uniform_notifier
16
- requirement: &70142210251740 !ruby/object:Gem::Requirement
16
+ requirement: &70204227570640 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 1.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70142210251740
24
+ version_requirements: *70204227570640
25
25
  description: A rails plugin to kill N+1 queries and unused eager loading.
26
26
  email:
27
27
  - flyerhzm@gmail.com
@@ -34,9 +34,9 @@ files:
34
34
  - .rvmrc
35
35
  - .rvmrc.example
36
36
  - .travis.yml
37
- - .watchr
38
37
  - Gemfile
39
38
  - Gemfile.lock
39
+ - Guardfile
40
40
  - Hacking.textile
41
41
  - MIT-LICENSE
42
42
  - README.textile
@@ -68,12 +68,57 @@ files:
68
68
  - lib/bullet/version.rb
69
69
  - perf/benchmark.rb
70
70
  - rails/init.rb
71
- - spec/bullet/association_for_chris_spec.rb
72
- - spec/bullet/association_for_peschkaj_spec.rb
73
- - spec/bullet/association_spec.rb
74
- - spec/bullet/counter_spec.rb
71
+ - spec/bullet/detector/association_spec.rb
72
+ - spec/bullet/detector/base_spec.rb
73
+ - spec/bullet/detector/counter_spec.rb
74
+ - spec/bullet/detector/n_plus_one_query_spec.rb
75
+ - spec/bullet/detector/unused_eager_association_spec.rb
76
+ - spec/bullet/notification/base_spec.rb
77
+ - spec/bullet/notification/counter_cache_spec.rb
78
+ - spec/bullet/notification/n_plus_one_query_spec.rb
79
+ - spec/bullet/notification/unused_eager_loading_spec.rb
80
+ - spec/bullet/notification_collector_spec.rb
75
81
  - spec/bullet/rack_spec.rb
82
+ - spec/bullet/registry/association_spec.rb
83
+ - spec/bullet/registry/base_spec.rb
84
+ - spec/bullet/registry/object_spec.rb
85
+ - spec/integration/association_for_chris_spec.rb
86
+ - spec/integration/association_for_peschkaj_spec.rb
87
+ - spec/integration/association_spec.rb
88
+ - spec/integration/counter_spec.rb
89
+ - spec/models/address.rb
90
+ - spec/models/author.rb
91
+ - spec/models/base_user.rb
92
+ - spec/models/category.rb
93
+ - spec/models/city.rb
94
+ - spec/models/client.rb
95
+ - spec/models/comment.rb
96
+ - spec/models/company.rb
97
+ - spec/models/contact.rb
98
+ - spec/models/country.rb
99
+ - spec/models/deal.rb
100
+ - spec/models/document.rb
101
+ - spec/models/email.rb
102
+ - spec/models/entry.rb
103
+ - spec/models/firm.rb
104
+ - spec/models/folder.rb
105
+ - spec/models/hotel.rb
106
+ - spec/models/location.rb
107
+ - spec/models/newspaper.rb
108
+ - spec/models/page.rb
109
+ - spec/models/person.rb
110
+ - spec/models/pet.rb
111
+ - spec/models/post.rb
112
+ - spec/models/relationship.rb
113
+ - spec/models/student.rb
114
+ - spec/models/submission.rb
115
+ - spec/models/teacher.rb
116
+ - spec/models/user.rb
117
+ - spec/models/writer.rb
76
118
  - spec/spec_helper.rb
119
+ - spec/support/bullet_ext.rb
120
+ - spec/support/rack_double.rb
121
+ - spec/support/seed.rb
77
122
  - tasks/bullet_tasks.rake
78
123
  homepage: http://github.com/flyerhzm/bullet
79
124
  licenses: []
@@ -89,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
134
  version: '0'
90
135
  segments:
91
136
  - 0
92
- hash: -891202166897363067
137
+ hash: -2125983168310894132
93
138
  required_rubygems_version: !ruby/object:Gem::Requirement
94
139
  none: false
95
140
  requirements:
@@ -103,9 +148,54 @@ signing_key:
103
148
  specification_version: 3
104
149
  summary: A rails plugin to kill N+1 queries and unused eager loading.
105
150
  test_files:
106
- - spec/bullet/association_for_chris_spec.rb
107
- - spec/bullet/association_for_peschkaj_spec.rb
108
- - spec/bullet/association_spec.rb
109
- - spec/bullet/counter_spec.rb
151
+ - spec/bullet/detector/association_spec.rb
152
+ - spec/bullet/detector/base_spec.rb
153
+ - spec/bullet/detector/counter_spec.rb
154
+ - spec/bullet/detector/n_plus_one_query_spec.rb
155
+ - spec/bullet/detector/unused_eager_association_spec.rb
156
+ - spec/bullet/notification/base_spec.rb
157
+ - spec/bullet/notification/counter_cache_spec.rb
158
+ - spec/bullet/notification/n_plus_one_query_spec.rb
159
+ - spec/bullet/notification/unused_eager_loading_spec.rb
160
+ - spec/bullet/notification_collector_spec.rb
110
161
  - spec/bullet/rack_spec.rb
162
+ - spec/bullet/registry/association_spec.rb
163
+ - spec/bullet/registry/base_spec.rb
164
+ - spec/bullet/registry/object_spec.rb
165
+ - spec/integration/association_for_chris_spec.rb
166
+ - spec/integration/association_for_peschkaj_spec.rb
167
+ - spec/integration/association_spec.rb
168
+ - spec/integration/counter_spec.rb
169
+ - spec/models/address.rb
170
+ - spec/models/author.rb
171
+ - spec/models/base_user.rb
172
+ - spec/models/category.rb
173
+ - spec/models/city.rb
174
+ - spec/models/client.rb
175
+ - spec/models/comment.rb
176
+ - spec/models/company.rb
177
+ - spec/models/contact.rb
178
+ - spec/models/country.rb
179
+ - spec/models/deal.rb
180
+ - spec/models/document.rb
181
+ - spec/models/email.rb
182
+ - spec/models/entry.rb
183
+ - spec/models/firm.rb
184
+ - spec/models/folder.rb
185
+ - spec/models/hotel.rb
186
+ - spec/models/location.rb
187
+ - spec/models/newspaper.rb
188
+ - spec/models/page.rb
189
+ - spec/models/person.rb
190
+ - spec/models/pet.rb
191
+ - spec/models/post.rb
192
+ - spec/models/relationship.rb
193
+ - spec/models/student.rb
194
+ - spec/models/submission.rb
195
+ - spec/models/teacher.rb
196
+ - spec/models/user.rb
197
+ - spec/models/writer.rb
111
198
  - spec/spec_helper.rb
199
+ - spec/support/bullet_ext.rb
200
+ - spec/support/rack_double.rb
201
+ - spec/support/seed.rb
data/.watchr DELETED
@@ -1,24 +0,0 @@
1
- # vim:set filetype=ruby:
2
- def run(cmd)
3
- puts cmd
4
- system cmd
5
- end
6
-
7
- def spec(file)
8
- if File.exists?(file)
9
- run("rspec #{file}")
10
- else
11
- puts("Spec: #{file} does not exist.")
12
- end
13
- end
14
-
15
- watch("spec/.*/*_spec\.rb") do |match|
16
- puts(match[0])
17
- spec(match[0])
18
- end
19
-
20
- watch("lib/(.*/.*)\.rb") do |match|
21
- puts(match[1])
22
- spec("spec/#{match[1]}_spec.rb")
23
- end
24
-