rspec-activerecord-expectations 1.1.0 → 1.2.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/.github/workflows/main.yml +5 -6
- data/CHANGELOG.md +7 -1
- data/README.md +25 -10
- data/lib/rspec/activerecord/expectations/collector.rb +9 -5
- data/lib/rspec/activerecord/expectations/matchers/query_count.rb +23 -3
- data/lib/rspec/activerecord/expectations/query_inspector.rb +19 -0
- data/lib/rspec/activerecord/expectations.rb +1 -0
- data/rspec-activerecord-expectations.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea0eb161965acaf677cec0de83466eece5379423903fc0a04b181cabe61a8121
|
4
|
+
data.tar.gz: 4df14e9211baf4ac6f3935a68b910191480f6f6af622f36c7d7e51a90374d222
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75bd827d5d0fc6566ba54f48cd432fab6cad301f2b5eb781383ea227ec74e2699733026fc22086899ac8bf725280e9cb1a5d7ca42545074cee1eb932142f9d93
|
7
|
+
data.tar.gz: ad9f387210fb8d30c06b5177a51b934a415d36805d94729d8117408200b241ee3f9408884bfbe63ab2bc93b28118f69a13dbe1aa05e3a2eb80bf04705a6b3de4
|
data/.github/workflows/main.yml
CHANGED
@@ -15,7 +15,7 @@ jobs:
|
|
15
15
|
rails: ['5.0', '5.1', '5.2', '6.0', '6.1', '7.0']
|
16
16
|
|
17
17
|
runs-on: ${{ matrix.os }}
|
18
|
-
name:
|
18
|
+
name: ruby ${{ matrix.ruby_version }}, rails ${{ matrix.rails }}, ${{ matrix.os }}
|
19
19
|
|
20
20
|
steps:
|
21
21
|
- uses: actions/checkout@v2
|
@@ -26,7 +26,7 @@ jobs:
|
|
26
26
|
ruby_version: ${{ matrix.ruby_version }}
|
27
27
|
bundler-cache: true
|
28
28
|
|
29
|
-
- name: Install
|
29
|
+
- name: Install Gems w/ Rails ${{ matrix.rails }}
|
30
30
|
env:
|
31
31
|
MATRIX_RAILS_VERSION: ${{ matrix.rails }}
|
32
32
|
run: |
|
@@ -40,12 +40,11 @@ jobs:
|
|
40
40
|
test_legacy:
|
41
41
|
strategy:
|
42
42
|
matrix:
|
43
|
-
os: [ubuntu-latest, macos-latest]
|
44
43
|
ruby_version: ['2.6', '2.5', '2.4', '2.3']
|
45
44
|
rails: ['5.0', '5.1', '5.2']
|
46
45
|
|
47
|
-
runs-on:
|
48
|
-
name:
|
46
|
+
runs-on: ubuntu-latest
|
47
|
+
name: legacy ruby ${{ matrix.ruby_version }}, rails ${{ matrix.rails }}
|
49
48
|
|
50
49
|
steps:
|
51
50
|
- uses: actions/checkout@v2
|
@@ -56,7 +55,7 @@ jobs:
|
|
56
55
|
ruby_version: ${{ matrix.ruby_version }}
|
57
56
|
bundler-cache: true
|
58
57
|
|
59
|
-
- name: Install
|
58
|
+
- name: Install Gems w/ Rails ${{ matrix.rails }}
|
60
59
|
env:
|
61
60
|
MATRIX_RAILS_VERSION: ${{ matrix.rails }}
|
62
61
|
run: |
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [1.2.0] - 2020-12-31
|
4
|
+
- Add `query` as a synonym for `queries`
|
5
|
+
- Ignore schema and transaction queries in query count
|
6
|
+
- Add beginning of recording specific query types
|
7
|
+
- Add query count matcher for `exactly`
|
8
|
+
|
3
9
|
## [1.1.0] - 2020-12-30
|
4
|
-
- Add matchers for less_than_or_equal_to
|
10
|
+
- Add query count matchers for e.g. `less_than_or_equal_to`, `greater_than`
|
5
11
|
|
6
12
|
## [1.0.1] - 2020-12-30
|
7
13
|
- Pin all the dependencies to a proper working subset
|
data/README.md
CHANGED
@@ -91,9 +91,12 @@ That's it! Refactor your report to be more efficient and then leave the test in
|
|
91
91
|
place to make sure that future developers don't accidentally cause a
|
92
92
|
performance regression.
|
93
93
|
|
94
|
-
##
|
94
|
+
## Counting Queries
|
95
95
|
|
96
|
-
|
96
|
+
### Types of Comparisons
|
97
|
+
|
98
|
+
Several comparison types are available, along with some aliases to allow for
|
99
|
+
easier to read tests.
|
97
100
|
|
98
101
|
```ruby
|
99
102
|
expect {}.to execute.less_than(20).queries
|
@@ -107,6 +110,25 @@ expect {}.to execute.more_than(20).queries
|
|
107
110
|
|
108
111
|
expect {}.to execute.greater_than_or_equal_to(20).queries
|
109
112
|
expect {}.to execute.at_least(20).queries
|
113
|
+
|
114
|
+
expect {}.to execute.exactly(20).queries
|
115
|
+
|
116
|
+
expect {}.to execute.at_least(2).queries
|
117
|
+
expect {}.to execute.at_least(1).query # singular form also accepted
|
118
|
+
```
|
119
|
+
|
120
|
+
### Specific Query Types
|
121
|
+
|
122
|
+
You can of course make assertions for the total number of queries executed, but
|
123
|
+
sometimes it's more valuable to assert particular _types_ of queries, such as
|
124
|
+
inserts or find statements. Matchers are supported for this as well!
|
125
|
+
|
126
|
+
**Note**: Transaction (for example, `ROLLBACK`) queries are not counted in any of these
|
127
|
+
categories, nor are queries that load the DB schema.
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
expect {}.to execute.exactly(20).queries
|
131
|
+
expect {}.to execute.exactly(20).insert_queries
|
110
132
|
```
|
111
133
|
|
112
134
|
## Future Planned Functionality
|
@@ -114,10 +136,7 @@ expect {}.to execute.at_least(20).queries
|
|
114
136
|
This gem still has lots of future functionality. See below.
|
115
137
|
|
116
138
|
```ruby
|
117
|
-
expect {}.to execute.exactly(5).queries
|
118
|
-
|
119
139
|
expect {}.to execute.at_least(2).activerecord_queries
|
120
|
-
expect {}.to execute.at_least(2).insert_queries
|
121
140
|
expect {}.to execute.at_least(2).delete_queries
|
122
141
|
expect {}.to execute.at_least(2).load_queries
|
123
142
|
expect {}.to execute.at_least(2).schema_queries
|
@@ -135,15 +154,11 @@ expect {}.to update.exactly(2).of_any_type
|
|
135
154
|
expect {}.to delete.exactly(2).of_any_type
|
136
155
|
|
137
156
|
expect {}.not_to repeatedly_load(Audited::Audit)
|
138
|
-
|
139
|
-
expect {}.to execute.at_least(1).query
|
140
157
|
```
|
141
158
|
|
142
|
-
- ignore transactionals (begin / rollback)
|
143
|
-
- `name: Foo Load`
|
144
159
|
- differentiate AR queries from generic ones? arbitrary execution somehow?
|
145
160
|
- warn about warmup
|
146
|
-
-
|
161
|
+
- warn if we smite any built in methods (or methods from other libs)
|
147
162
|
|
148
163
|
## Development
|
149
164
|
|
@@ -1,15 +1,16 @@
|
|
1
1
|
module RSpec::ActiveRecord::Expectations
|
2
2
|
class Collector
|
3
3
|
def initialize
|
4
|
-
@
|
5
|
-
|
6
|
-
|
4
|
+
@inspector = QueryInspector.new
|
5
|
+
@counts = QueryInspector.valid_query_types.each_with_object({}) do |query_type, hash|
|
6
|
+
hash[query_type] = 0
|
7
|
+
end
|
7
8
|
|
8
9
|
ActiveSupport::Notifications.subscribe("sql.active_record", method(:record_query))
|
9
10
|
end
|
10
11
|
|
11
12
|
def queries_of_type(type)
|
12
|
-
@counts
|
13
|
+
@counts[type] || (raise ArgumentError, "Sorry, #{type} is not a valid kind of query")
|
13
14
|
end
|
14
15
|
|
15
16
|
def valid_type?(type)
|
@@ -17,7 +18,10 @@ module RSpec::ActiveRecord::Expectations
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def record_query(*_unused, data)
|
20
|
-
|
21
|
+
categories = @inspector.categorize(data)
|
22
|
+
categories.each do |category|
|
23
|
+
@counts[category] += 1
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -54,13 +54,24 @@ module RSpec::ActiveRecord::Expectations
|
|
54
54
|
end
|
55
55
|
alias_method :at_least, :greater_than_or_equal_to
|
56
56
|
|
57
|
+
def exactly(n)
|
58
|
+
@comparison = n
|
59
|
+
@match_method = method(:compare_exactly)
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
57
63
|
# TARGET QUERY TYPES
|
58
64
|
|
59
|
-
|
60
|
-
|
61
|
-
|
65
|
+
RSpec::ActiveRecord::Expectations::QueryInspector.valid_query_types.each do |type|
|
66
|
+
define_method type do
|
67
|
+
@query_type = type
|
68
|
+
self
|
69
|
+
end
|
62
70
|
end
|
63
71
|
|
72
|
+
# TODO singularize everything
|
73
|
+
alias_method :query, :queries
|
74
|
+
|
64
75
|
private
|
65
76
|
|
66
77
|
# MATCHERS
|
@@ -102,6 +113,15 @@ module RSpec::ActiveRecord::Expectations
|
|
102
113
|
|
103
114
|
count >= @comparison
|
104
115
|
end
|
116
|
+
|
117
|
+
def compare_exactly
|
118
|
+
count = @collector.queries_of_type(@query_type)
|
119
|
+
|
120
|
+
@failure_message = "expected block to execute at #{@comparison} queries, but it executed #{count}"
|
121
|
+
@failure_message_when_negated = "expected block not to execute #{@comparison} queries, but it executed #{count}"
|
122
|
+
|
123
|
+
count == @comparison
|
124
|
+
end
|
105
125
|
end
|
106
126
|
end
|
107
127
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RSpec::ActiveRecord::Expectations
|
2
|
+
class QueryInspector
|
3
|
+
def self.valid_query_types
|
4
|
+
[:queries, :schema_queries, :transaction_queries, :insert_queries]
|
5
|
+
end
|
6
|
+
|
7
|
+
def categorize(query)
|
8
|
+
if query[:name] == "SCHEMA"
|
9
|
+
[:schema_queries]
|
10
|
+
elsif query[:name] == "TRANSACTION"
|
11
|
+
[:transaction_queries]
|
12
|
+
elsif query[:name] =~ /Create$/
|
13
|
+
[:queries, :insert_queries]
|
14
|
+
else
|
15
|
+
[:queries]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-activerecord-expectations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Mastey
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -103,6 +103,7 @@ files:
|
|
103
103
|
- lib/rspec/activerecord/expectations/collector.rb
|
104
104
|
- lib/rspec/activerecord/expectations/errors.rb
|
105
105
|
- lib/rspec/activerecord/expectations/matchers/query_count.rb
|
106
|
+
- lib/rspec/activerecord/expectations/query_inspector.rb
|
106
107
|
- rspec-activerecord-expectations.gemspec
|
107
108
|
homepage: https://github.com/jmmastey/rspec-activerecord-expectations
|
108
109
|
licenses:
|