rspec-sqlimit 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/.travis.yml +1 -1
- data/CHANGELOG.md +18 -0
- data/README.md +6 -27
- data/Rakefile +1 -1
- data/lib/rspec/sqlimit/counter.rb +5 -1
- data/lib/rspec/sqlimit/reporter.rb +2 -1
- data/rspec-sqlimit.gemspec +1 -1
- data/spec/dummy/db/migrate/20170211104800_create_users.rb +1 -1
- data/spec/rspec/sqlimit/reporter_spec.rb +43 -0
- data/spec/rspec/sqlimit_spec.rb +16 -0
- metadata +6 -4
- data/spec/dummy/db/test.sqlite3 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb112af9504128b90adde574c3ec62eb7853a35e
|
4
|
+
data.tar.gz: 5a7a2d7ed16fc1224168435263f27d59e943530d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 943305eafecad8557ed1ef7baaca8eb02ae9c2f05da61f538c6412fb49a568ac5df7e686c8455b47fc20d919ade80704d071e328197c51d54b96e6699d7b8b24
|
7
|
+
data.tar.gz: 8cede3b49a91a9ce2ab17869e94fa4a674c157ecd7043f73a95a0d25552fb51e63b4648a7cc2c2c1320642233f585234137a087ca71a2954f6c7c3b34a50af58
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
|
+
|
8
|
+
## [0.0.2] - [2017-05-17]
|
9
|
+
|
10
|
+
### Added
|
11
|
+
- All variables of SQL queries are bound to error messages (@Dobrodushny)
|
12
|
+
|
13
|
+
## [0.0.1] - [2017-02-12]
|
14
|
+
This is a first public release (@nepalez)
|
15
|
+
|
16
|
+
[Unreleased]: https://github.com/tram-rb/tram-policy
|
17
|
+
[0.0.1]: https://github.com/nepalez/rspec-sqlimit/releases/tag/v0.0.1
|
18
|
+
[0.0.2]: https://github.com/nepalez/rspec-sqlimit/compare/v0.0.1...v0.0.2
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@ RSpec matcher to control number of SQL queries executed by a block of code.
|
|
4
4
|
|
5
5
|
It wraps [the answer at Stack Overflow][stack-answer] by [Ryan Bigg][ryan-bigg], which based on Active Support [Notification][notification] and [Instrumentation][instrumentation] mechanisms.
|
6
6
|
|
7
|
+
For motivation and details see my [blog post "Fighting the Hydra of N+1 queries" in the Martian Chronicles][hydra].
|
8
|
+
|
7
9
|
[![Gem Version][gem-badger]][gem]
|
8
10
|
[![Build Status][travis-badger]][travis]
|
9
11
|
[![Dependency Status][gemnasium-badger]][gemnasium]
|
@@ -66,31 +68,7 @@ require "rspec-sqlimit"
|
|
66
68
|
|
67
69
|
RSpec.describe "N+1 safety" do
|
68
70
|
it "doesn't send unnecessary requests to db" do
|
69
|
-
expect { User.create }.not_to exceed_query_limit(1).with(/^INSERT/)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
```
|
73
|
-
|
74
|
-
```
|
75
|
-
Failure/Error: expect { User.create }.not_to exceed_query_limit(0).with(/INSERT/)
|
76
|
-
|
77
|
-
Expected to run maximum 0 queries that match (?-mix:INSERT)
|
78
|
-
The following 1 queries were invoked among others (see mark ->):
|
79
|
-
1) begin transaction (0.072 ms)
|
80
|
-
-> 2) INSERT INTO "users" DEFAULT VALUES (0.368 ms)
|
81
|
-
3) commit transaction (147.559 ms)
|
82
|
-
```
|
83
|
-
|
84
|
-
## Further Development
|
85
|
-
|
86
|
-
For now the gem uses unbinded Active Record queries in error descriptions. For example, when your query contains arguments, the error message will look like
|
87
|
-
|
88
|
-
```ruby
|
89
|
-
require "rspec-sqlimit"
|
90
|
-
|
91
|
-
RSpec.describe "N+1 safety" do
|
92
|
-
it "doesn't send unnecessary requests to db" do
|
93
|
-
expect { User.create(name: "Joe") }.not_to exceed_query_limit(1)
|
71
|
+
expect { User.create name: "Joe" }.not_to exceed_query_limit(1).with(/^INSERT/)
|
94
72
|
end
|
95
73
|
end
|
96
74
|
```
|
@@ -101,11 +79,11 @@ Failure/Error: expect { User.create }.not_to exceed_query_limit(0).with(/INSERT/
|
|
101
79
|
Expected to run maximum 0 queries that match (?-mix:INSERT)
|
102
80
|
The following 1 queries were invoked among others (see mark ->):
|
103
81
|
1) begin transaction (0.072 ms)
|
104
|
-
-> 2) INSERT INTO "users" ("name") VALUES (?) (0.368 ms)
|
82
|
+
-> 2) INSERT INTO "users" ("name") VALUES (?); ["Joe"] (0.368 ms)
|
105
83
|
3) commit transaction (147.559 ms)
|
106
84
|
```
|
107
85
|
|
108
|
-
|
86
|
+
In the last example you can see that binded values are shown after the query following the Rails convention.
|
109
87
|
|
110
88
|
## License
|
111
89
|
|
@@ -124,3 +102,4 @@ The gem is available as open source under the terms of the [MIT License](http://
|
|
124
102
|
[notification]: http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html
|
125
103
|
[instrumentation]: http://guides.rubyonrails.org/active_support_instrumentation.html
|
126
104
|
[hook]: http://guides.rubyonrails.org/active_support_instrumentation.html#sql-active-record
|
105
|
+
[hydra]: https://evilmartians.com/chronicles/fighting-the-hydra-of-n-plus-one-queries
|
data/Rakefile
CHANGED
@@ -31,7 +31,11 @@ module RSpec::SQLimit
|
|
31
31
|
def callback
|
32
32
|
@callback ||= lambda do |_name, start, finish, _message_id, values|
|
33
33
|
return if %w(CACHE SCHEMA).include? values[:name]
|
34
|
-
queries << {
|
34
|
+
queries << {
|
35
|
+
sql: values[:sql],
|
36
|
+
duration: (finish - start) * 1_000,
|
37
|
+
binds: values[:type_casted_binds]
|
38
|
+
}
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
@@ -28,7 +28,8 @@ module RSpec::SQLimit
|
|
28
28
|
|
29
29
|
def line(query, index)
|
30
30
|
prefix = (matcher && query[:sql] =~ matcher) ? "->" : " "
|
31
|
-
|
31
|
+
binds = query[:binds].any? ? "; #{query[:binds]} " : ''
|
32
|
+
"#{prefix} #{index + 1}) #{query[:sql]}#{binds} (#{query[:duration].round(3)} ms)"
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
data/rspec-sqlimit.gemspec
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RSpec::SQLimit::Reporter do
|
4
|
+
subject { described_class.new(counter) }
|
5
|
+
|
6
|
+
context 'no params were passed to the query' do
|
7
|
+
let(:counter) { RSpec::SQLimit::Counter[/CREATE/, Proc.new{ User.create }] }
|
8
|
+
|
9
|
+
it "doesn't print binds" do
|
10
|
+
# INSERT INTO "users" DEFAULT VALUES (0.284 ms)
|
11
|
+
expect(subject.call).to include("DEFAULT VALUES")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'query contains params' do
|
16
|
+
context 'nil was passed as param' do
|
17
|
+
let(:counter) { RSpec::SQLimit::Counter[/CREATE/, Proc.new{ User.create(id: nil) }] }
|
18
|
+
|
19
|
+
it "doesn't print binds" do
|
20
|
+
# INSERT INTO "users" DEFAULT VALUES (0.284 ms)
|
21
|
+
expect(subject.call).to include("DEFAULT VALUES")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'single param was passed' do
|
26
|
+
let(:counter) { RSpec::SQLimit::Counter[/CREATE/, Proc.new{ User.create(id: 1) }] }
|
27
|
+
|
28
|
+
it 'prints param as an array with one element' do
|
29
|
+
# INSERT INTO "users" ("id") VALUES (?); [1] (0.234 ms)
|
30
|
+
expect(subject.call).to include("VALUES (?); [1]")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'array was passed as a param' do
|
35
|
+
let(:counter) { RSpec::SQLimit::Counter[/SELECT/, Proc.new{ User.where(id: [1, 2, 3]).to_a }] }
|
36
|
+
|
37
|
+
it 'prints all params' do
|
38
|
+
# SELECT "users".* FROM "users" WHERE "users"."id" IN (1, 2, 3) (0.17 ms))
|
39
|
+
expect(subject.call).to include("IN (1, 2, 3)")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/rspec/sqlimit_spec.rb
CHANGED
@@ -6,6 +6,14 @@ describe "exceed_query_limit" do
|
|
6
6
|
expect { User.new }.not_to exceed_query_limit(0)
|
7
7
|
end
|
8
8
|
|
9
|
+
it "works when nil is used as a parameter" do
|
10
|
+
expect { User.create id: nil }.to exceed_query_limit(0)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "works when array is used as a restriction" do
|
14
|
+
expect { (User.where id: [1, 2, 3]).to_a }.to exceed_query_limit(0)
|
15
|
+
end
|
16
|
+
|
9
17
|
it "works when actual number of queries is below the limit" do
|
10
18
|
expect { User.create }.not_to exceed_query_limit(3)
|
11
19
|
end
|
@@ -20,6 +28,14 @@ describe "exceed_query_limit" do
|
|
20
28
|
expect { User.new }.not_to exceed_query_limit(0).with(/INSERT/)
|
21
29
|
end
|
22
30
|
|
31
|
+
it "works when nil is used as a parameter" do
|
32
|
+
expect { User.create id: nil }.to exceed_query_limit(0).with(/INSERT/)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "works when array is used as a restriction" do
|
36
|
+
expect { (User.where id: [1, 2, 3]).to_a }.to exceed_query_limit(0).with(/SELECT/)
|
37
|
+
end
|
38
|
+
|
23
39
|
it "works when actual number of queries is below the limit" do
|
24
40
|
expect { User.create }.not_to exceed_query_limit(1).with(/INSERT/)
|
25
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-sqlimit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kozin (nepalez)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -120,12 +120,14 @@ executables: []
|
|
120
120
|
extensions: []
|
121
121
|
extra_rdoc_files:
|
122
122
|
- README.md
|
123
|
+
- CHANGELOG.md
|
123
124
|
files:
|
124
125
|
- ".codeclimate.yml"
|
125
126
|
- ".gitignore"
|
126
127
|
- ".rspec"
|
127
128
|
- ".rubocop.yml"
|
128
129
|
- ".travis.yml"
|
130
|
+
- CHANGELOG.md
|
129
131
|
- Gemfile
|
130
132
|
- LICENSE.txt
|
131
133
|
- README.md
|
@@ -141,9 +143,9 @@ files:
|
|
141
143
|
- spec/dummy/config/environment.rb
|
142
144
|
- spec/dummy/db/migrate/20170211104800_create_users.rb
|
143
145
|
- spec/dummy/db/schema.rb
|
144
|
-
- spec/dummy/db/test.sqlite3
|
145
146
|
- spec/dummy/lib/dummy.rb
|
146
147
|
- spec/dummy/lib/dummy/application.rb
|
148
|
+
- spec/rspec/sqlimit/reporter_spec.rb
|
147
149
|
- spec/rspec/sqlimit_spec.rb
|
148
150
|
- spec/spec_helper.rb
|
149
151
|
homepage: https://github.com/nepalez/rspec-sqlimit
|
@@ -177,8 +179,8 @@ test_files:
|
|
177
179
|
- spec/dummy/config/environment.rb
|
178
180
|
- spec/dummy/db/migrate/20170211104800_create_users.rb
|
179
181
|
- spec/dummy/db/schema.rb
|
180
|
-
- spec/dummy/db/test.sqlite3
|
181
182
|
- spec/dummy/lib/dummy.rb
|
182
183
|
- spec/dummy/lib/dummy/application.rb
|
184
|
+
- spec/rspec/sqlimit/reporter_spec.rb
|
183
185
|
- spec/rspec/sqlimit_spec.rb
|
184
186
|
- spec/spec_helper.rb
|
data/spec/dummy/db/test.sqlite3
DELETED
Binary file
|