rspec-activerecord-expectations 2.1.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +54 -5
- data/lib/rspec/activerecord/expectations/matchers/transaction_matcher.rb +70 -0
- data/lib/rspec/activerecord/expectations/query_inspector.rb +8 -3
- data/lib/rspec/activerecord/expectations.rb +17 -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: 3205b050d5f2164b5bc72de9fe29a0f6d988cd869ecd6703a09b83b2550bb02e
|
4
|
+
data.tar.gz: d43d363888f5c8f85dc551fae7d1381a945ac304c597192544ffd1506d1f7495
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a98cfac5ba127c3e5f7bd2b42ef48fa56e6750e75d0ab841988b076a2a39c0ca13e5d67e534020fd81af3b7885cba3d192c23a2fbb0b4ccd0d8e725e3cafb147
|
7
|
+
data.tar.gz: 65347df27d406531b1ea594bfe9a3d9b6405c75ad5f8be5c3f52f668e3d976e0e73c5e1560caeb308cb203b73547ab18c0ffd758aff0e913a9f010665a0a6595
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.2.0] - 2022-01-14
|
4
|
+
- Adds transaction matcher to verify that code was executed within a
|
5
|
+
transaction at minimum
|
6
|
+
- Transaction matcher also allows for commits and rollbacks
|
7
|
+
- Update README for accompanying functionality
|
8
|
+
|
3
9
|
## [2.1.1] - 2022-01-12
|
4
10
|
- Gemspec is really generated using the version of ruby that's locally in use.
|
5
11
|
Update that build artifact to use non-java dependencies.
|
data/README.md
CHANGED
@@ -181,7 +181,57 @@ expect {}.to execute.exactly(20).transaction_queries
|
|
181
181
|
categories, nor are queries that load the DB schema.
|
182
182
|
|
183
183
|
**Note:** Destroy and delete queries are both condensed into the matcher for
|
184
|
-
`destroy_queries`.
|
184
|
+
the errorthe error `destroy_queries`.
|
185
|
+
|
186
|
+
## Transaction Management
|
187
|
+
|
188
|
+
Sometimes, it makes sense to monitor whether database transactions were
|
189
|
+
successful or not. This is very similar to using `expect{}.to change(SomeModel,
|
190
|
+
:count)` in a spec, but nonetheless it can be useful to assert transactions
|
191
|
+
themselves. Some assertions are available for this purpose.
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
expect {}.to execute_a_transaction
|
195
|
+
expect {}.to rollback_a_transaction
|
196
|
+
expect {}.to roll_back_a_transaction
|
197
|
+
expect {}.to commit_a_transaction
|
198
|
+
```
|
199
|
+
|
200
|
+
A complication to this scheme is that Rails tries not to make unnecessary database
|
201
|
+
calls, which means that attempting to save a model that has failing validations
|
202
|
+
won't actually attempt to save to the database.
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
expect {
|
206
|
+
MyClass.create!(required_field: nil)
|
207
|
+
}.to rollback_a_transaction
|
208
|
+
```
|
209
|
+
|
210
|
+
This assertion will fail, as `create!` will never make it as far as the
|
211
|
+
database. That said, if you manually create a transaction, _and you select
|
212
|
+
data within that transaction_, you may assert a rollback.
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
expect {
|
216
|
+
MyClass.first # triggers the transaction
|
217
|
+
MyClass.create!(required_field: nil)
|
218
|
+
}.to rollback_a_transaction
|
219
|
+
```
|
220
|
+
|
221
|
+
It you need to make transaction-related assertions of this sort, your best bet
|
222
|
+
may be to assert that a commit statement was _not_ issued.
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
expect do
|
226
|
+
MyClass.create!(required_field: nil)
|
227
|
+
rescue
|
228
|
+
# NOOP
|
229
|
+
end.not_to rollback_a_transaction
|
230
|
+
```
|
231
|
+
|
232
|
+
Note that ActiveRecord will not only roll back the transaction, but also
|
233
|
+
re-raise errors. As such, it's necessary in this example to rescue that
|
234
|
+
error in order for the test to fail.
|
185
235
|
|
186
236
|
## Future Planned Functionality
|
187
237
|
|
@@ -194,14 +244,13 @@ expect {}.to execute.at_least(2).load_queries("Audited::Audit")
|
|
194
244
|
expect {}.to execute.at_least(2).activerecord_queries
|
195
245
|
expect {}.to execute.at_least(2).hand_rolled_queries
|
196
246
|
|
197
|
-
expect {}.not_to rollback_transaction.exactly(5).times
|
198
|
-
expect {}.not_to commit_transaction.once
|
199
|
-
expect {}.to run_a_transaction
|
200
|
-
|
201
247
|
expect {}.to create.exactly(5).of_type(User)
|
202
248
|
expect {}.to insert.exactly(5).subscription_changes
|
203
249
|
expect {}.to update.exactly(2).of_any_type
|
204
250
|
expect {}.to delete.exactly(2).of_any_type
|
251
|
+
|
252
|
+
expect {}.to commit_a_transaction.once
|
253
|
+
expect {}.to rollback_a_transaction.exactly(5).times
|
205
254
|
```
|
206
255
|
|
207
256
|
- warn if we smite any built in methods (or methods from other libs)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RSpec::ActiveRecord::Expectations
|
2
|
+
module Matchers
|
3
|
+
class TransactionMatcher
|
4
|
+
def initialize(transaction_type)
|
5
|
+
@collector = Collector.new
|
6
|
+
@transaction = transaction_type
|
7
|
+
end
|
8
|
+
|
9
|
+
def supports_block_expectations?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def matches?(block)
|
14
|
+
block.call
|
15
|
+
|
16
|
+
@count = @collector.queries_of_type(@transaction)
|
17
|
+
@count > 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_message
|
21
|
+
type_msg = case @transaction
|
22
|
+
when :transaction_queries
|
23
|
+
"execute a transaction"
|
24
|
+
when :rollback_queries
|
25
|
+
"roll back a transaction"
|
26
|
+
when :commit_queries
|
27
|
+
"commit a transaction"
|
28
|
+
end
|
29
|
+
|
30
|
+
"expected block to #{type_msg}, but it didn't do so"
|
31
|
+
end
|
32
|
+
|
33
|
+
def failure_message_when_negated
|
34
|
+
if @count == 1
|
35
|
+
negated_message_singular
|
36
|
+
else
|
37
|
+
negated_message_plural
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def negated_message_singular
|
44
|
+
pre_msg, post_msg = case @transaction
|
45
|
+
when :transaction_queries
|
46
|
+
["execute a transaction", "executed one"]
|
47
|
+
when :rollback_queries
|
48
|
+
["roll back a transaction", "rolled one back"]
|
49
|
+
when :commit_queries
|
50
|
+
["commit a transaction", "committed one"]
|
51
|
+
end
|
52
|
+
|
53
|
+
"expected block not to #{pre_msg}, but it #{post_msg}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def negated_message_plural
|
57
|
+
pre_msg, post_msg = case @transaction
|
58
|
+
when :transaction_queries
|
59
|
+
["execute a transaction", "executed #{@count} transactions"]
|
60
|
+
when :rollback_queries
|
61
|
+
["roll back a transaction", "rolled back #{@count} transactions"]
|
62
|
+
when :commit_queries
|
63
|
+
["commit a transaction", "committed #{@count} transactions"]
|
64
|
+
end
|
65
|
+
|
66
|
+
"expected block not to #{pre_msg}, but it #{post_msg}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,14 +1,19 @@
|
|
1
1
|
module RSpec::ActiveRecord::Expectations
|
2
2
|
class QueryInspector
|
3
3
|
def self.valid_query_types
|
4
|
-
[:queries, :schema_queries, :
|
5
|
-
:
|
4
|
+
[:queries, :schema_queries, :insert_queries, :load_queries,
|
5
|
+
:destroy_queries, :exists_queries,
|
6
|
+
:transaction_queries, :commit_queries, :rollback_queries]
|
6
7
|
end
|
7
8
|
|
8
9
|
def categorize(query)
|
9
10
|
if query[:name] == "SCHEMA"
|
10
11
|
[:schema_queries]
|
11
|
-
elsif query[:
|
12
|
+
elsif query[:sql] =~ /^commit/i
|
13
|
+
[:commit_queries]
|
14
|
+
elsif query[:sql] =~ /^rollback/i
|
15
|
+
[:rollback_queries]
|
16
|
+
elsif query[:name] == "TRANSACTION"
|
12
17
|
[:transaction_queries]
|
13
18
|
elsif query[:name] =~ /Create$/
|
14
19
|
[:queries, :insert_queries]
|
@@ -8,6 +8,22 @@ module RSpec
|
|
8
8
|
def repeatedly_load(klass)
|
9
9
|
Matchers::LoadMatcher.new(klass)
|
10
10
|
end
|
11
|
+
|
12
|
+
def execute_a_transaction
|
13
|
+
Matchers::TransactionMatcher.new(:transaction_queries)
|
14
|
+
end
|
15
|
+
|
16
|
+
def rollback_a_transaction
|
17
|
+
Matchers::TransactionMatcher.new(:rollback_queries)
|
18
|
+
end
|
19
|
+
|
20
|
+
def roll_back_a_transaction
|
21
|
+
Matchers::TransactionMatcher.new(:rollback_queries)
|
22
|
+
end
|
23
|
+
|
24
|
+
def commit_a_transaction
|
25
|
+
Matchers::TransactionMatcher.new(:commit_queries)
|
26
|
+
end
|
11
27
|
end
|
12
28
|
end
|
13
29
|
end
|
@@ -17,3 +33,4 @@ require_relative 'expectations/query_inspector'
|
|
17
33
|
require_relative 'expectations/collector'
|
18
34
|
require_relative 'expectations/matchers/query_count_matcher'
|
19
35
|
require_relative 'expectations/matchers/load_matcher'
|
36
|
+
require_relative 'expectations/matchers/transaction_matcher'
|
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: 2.
|
4
|
+
version: 2.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: 2022-01-
|
11
|
+
date: 2022-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -104,6 +104,7 @@ files:
|
|
104
104
|
- lib/rspec/activerecord/expectations/errors.rb
|
105
105
|
- lib/rspec/activerecord/expectations/matchers/load_matcher.rb
|
106
106
|
- lib/rspec/activerecord/expectations/matchers/query_count_matcher.rb
|
107
|
+
- lib/rspec/activerecord/expectations/matchers/transaction_matcher.rb
|
107
108
|
- lib/rspec/activerecord/expectations/query_inspector.rb
|
108
109
|
- rspec-activerecord-expectations.gemspec
|
109
110
|
homepage: https://github.com/jmmastey/rspec-activerecord-expectations
|