rspec-activerecord-expectations 1.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 202f92144b220ec281763d132152aa1bf3cced42d09273d3c050c8c41dab2018
4
- data.tar.gz: f4e4e5f4fce4c3db060c3ea1fcb6752d876fd8b41cc0337dc81308c6acfceb08
3
+ metadata.gz: d320c1e0f80e96c3bbb2cb07df63b941aa9bb1aa3878f9ca46e6fa1fed483569
4
+ data.tar.gz: 69487efb7a89d208d28a0d26faa3c74fc3315645803a1ec4162a6bd9f3677008
5
5
  SHA512:
6
- metadata.gz: fdbccf8e60640748b4eabc666355ac175455f0338a21a157d41eaee48f82361f45c4c921ec94ee2f3df5b9a274c72a1de868d4f7dfe5d3e2ff4480fbc08981ef
7
- data.tar.gz: d330ce04fee3e846d0591cd4f0c34599e3501715e291f7ad7956a226e7ca7d91638892a09e566f567e13daaf2287d7da95869e4c99e849043a459e7afcc599e0
6
+ metadata.gz: 7db71325cbfa0abd65c7128cceb18ba8017af399bee5cdd4502d84a988c3865605f0c5d34f858af352c1520b401651723fbf1c2335d652ec45f9ef0308a675bb
7
+ data.tar.gz: 44082fc8ad08369ea9e578f6cb3a11ec3dd7f92445b63ef4d415e10e14c79e350ded3a39828821b613513c382fd71b72db9b0669e7c14bd2e900655e03cffa5d
@@ -11,22 +11,22 @@ jobs:
11
11
  strategy:
12
12
  matrix:
13
13
  os: [ubuntu-latest, macos-latest]
14
- ruby_version: ['3.0', '2.7']
14
+ ruby-version: ['3.1', '3.0', '2.7']
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: Test ruby ${{ matrix.ruby_version }} / rails ${{ matrix.rails }} / ${{ matrix.os }}
18
+ name: ruby ${{ matrix.ruby-version }}, rails ${{ matrix.rails }}, ${{ matrix.os }}
19
19
 
20
20
  steps:
21
21
  - uses: actions/checkout@v2
22
22
 
23
- - name: Set up Ruby ${{ matrix.ruby_version }}
23
+ - name: Set up Ruby ${{ matrix.ruby-version }}
24
24
  uses: ruby/setup-ruby@v1
25
25
  with:
26
- ruby_version: ${{ matrix.ruby_version }}
26
+ ruby-version: ${{ matrix.ruby-version }}
27
27
  bundler-cache: true
28
28
 
29
- - name: Install correct gems / rails version
29
+ - name: Install Gems w/ Rails ${{ matrix.rails }}
30
30
  env:
31
31
  MATRIX_RAILS_VERSION: ${{ matrix.rails }}
32
32
  run: |
@@ -40,23 +40,51 @@ jobs:
40
40
  test_legacy:
41
41
  strategy:
42
42
  matrix:
43
- os: [ubuntu-latest, macos-latest]
44
- ruby_version: ['2.6', '2.5', '2.4', '2.3']
43
+ ruby-version: ['2.6', '2.5']
45
44
  rails: ['5.0', '5.1', '5.2']
46
45
 
47
- runs-on: ${{ matrix.os }}
48
- name: Test Legacy ruby ${{ matrix.ruby }} / rails ${{ matrix.rails }} / ${{ matrix.os }}
46
+ runs-on: ubuntu-latest
47
+ name: ruby ${{ matrix.ruby-version }}, rails ${{ matrix.rails }}
48
+
49
+ steps:
50
+ - uses: actions/checkout@v2
51
+
52
+ - name: Set up Ruby ${{ matrix.ruby-version }}
53
+ uses: ruby/setup-ruby@v1
54
+ with:
55
+ ruby-version: ${{ matrix.ruby-version }}
56
+ bundler-cache: true
57
+
58
+ - name: Install Gems w/ Rails ${{ matrix.rails }}
59
+ env:
60
+ MATRIX_RAILS_VERSION: ${{ matrix.rails }}
61
+ run: |
62
+ export BUNDLE_GEMFILE="${GITHUB_WORKSPACE}/gemfiles/rails_${MATRIX_RAILS_VERSION}.gemfile"
63
+ gem install bundler
64
+ bundle install --jobs 4 --retry 3
65
+
66
+ - name: Run tests
67
+ run: bundle exec rspec
68
+
69
+ test_alt_rubies:
70
+ strategy:
71
+ matrix:
72
+ ruby-version: ['jruby', 'truffleruby']
73
+ rails: ['6.0', '6.1'] # jruby / jdbc-sqlite3 end up tightly bound to rails 6.x
74
+
75
+ runs-on: ubuntu-latest
76
+ name: ${{ matrix.ruby-version }}, rails ${{ matrix.rails }}
49
77
 
50
78
  steps:
51
79
  - uses: actions/checkout@v2
52
80
 
53
- - name: Set up Ruby ${{ matrix.ruby_version }}
81
+ - name: Set up Ruby ${{ matrix.ruby-version }}
54
82
  uses: ruby/setup-ruby@v1
55
83
  with:
56
- ruby_version: ${{ matrix.ruby_version }}
84
+ ruby-version: ${{ matrix.ruby-version }}
57
85
  bundler-cache: true
58
86
 
59
- - name: Install correct gems / rails version
87
+ - name: Install Gems w/ Rails ${{ matrix.rails }}
60
88
  env:
61
89
  MATRIX_RAILS_VERSION: ${{ matrix.rails }}
62
90
  run: |
@@ -66,3 +94,4 @@ jobs:
66
94
 
67
95
  - name: Run tests
68
96
  run: bundle exec rspec
97
+
data/CHANGELOG.md CHANGED
@@ -1,10 +1,33 @@
1
1
  # Changelog
2
2
 
3
- ## [1.0.1] - 2020-12-30
3
+ ## [2.1.0] - 2022-01-12
4
+ - change CI matrix for more version compatibility
5
+ - update gemspec to move some deps into development only
6
+ - README changes
7
+
8
+ ## [2.0.0] - 2022-01-07
9
+ - Require much more recent ruby, to use syntax that's been around since 2017
10
+
11
+ ## [1.3.0] - 2021-12-31
12
+ - Add `repeatedly_load` matcher
13
+ - Add query type matchers for `load_queries`, `schema_queries`, `transaction_queries`, `destroy_queries`
14
+ - Allow singular version of all query types (e.g. `transaction_queries` vs `transaction_query`)
15
+ - Fix failure message for `execute.exactly` matcher
16
+
17
+ ## [1.2.0] - 2021-12-31
18
+ - Add `query` as a synonym for `queries`
19
+ - Ignore schema and transaction queries in query count
20
+ - Add beginning of recording specific query types
21
+ - Add query count matcher for `exactly`
22
+
23
+ ## [1.1.0] - 2021-12-30
24
+ - Add query count matchers for e.g. `less_than_or_equal_to`, `greater_than`
25
+
26
+ ## [1.0.1] - 2021-12-30
4
27
  - Pin all the dependencies to a proper working subset
5
28
  - Expand testing to many rails / ruby combinations
6
29
 
7
- ## [1.0.0] - 2020-12-30
30
+ ## [1.0.0] - 2021-12-30
8
31
  - Basic gem w/ all the fixins and README and such
9
32
  - Add `less_than` comparison, and `queries` type
10
33
  - Basic tests in place, and not bad tbh
data/README.md CHANGED
@@ -30,7 +30,8 @@ group 'test' do
30
30
  end
31
31
  ```
32
32
 
33
- Then, include the functionality within your spec helper (or in a support file).
33
+ Then, include the functionality within your `rails_helper.rb` (or in a support
34
+ file).
34
35
 
35
36
  ```ruby
36
37
  RSpec.configure do |config|
@@ -91,11 +92,91 @@ That's it! Refactor your report to be more efficient and then leave the test in
91
92
  place to make sure that future developers don't accidentally cause a
92
93
  performance regression.
93
94
 
94
- ## Supported Matchers
95
+ ## Preventing Repeated Load (N+1) Queries
96
+
97
+ Reloading, whether by e.g. `Album.find` or `album.tracks` are both antipatterns
98
+ within your code. They will load from the database for every iteration in a
99
+ loop, unless you load records outside the loop, cache responses, or use an
100
+ eager loading mechanism like `includes`. These sorts of queries are often
101
+ referred to as N+1 queries.
102
+
103
+ This sort of query can be prevented using the `repeatedly_load` expectation.
104
+
105
+ ```ruby
106
+ expect {}.not_to repeatedly_load('SomeActiveRecordClass')
107
+ ```
108
+
109
+ This matcher will track ActiveRecord's built in load methods to prevent those
110
+ N+1 situations. Using eager loading (e.g. `Track.all.includes(:album)`) will
111
+ allow these expectations to pass as expected!
112
+
113
+ ### Testing Batch Queries
114
+
115
+ If your code loads records in batches, it may be more difficult to create
116
+ expectations for repeated loading. After all, each batch will execute its own
117
+ queries, which may look like repeated loading.
118
+
119
+ If your test has a small enough number of records that only one batch is
120
+ loaded, your tests may work just fine. But otherwise, you may want to allow
121
+ your code to specify a batch size in order to guarantee only a single batch
122
+ is loaded:
95
123
 
96
124
  ```ruby
125
+ tracks = Track.all
126
+
127
+ expect {
128
+ TrackSerializer.perform(tracks, batch_size: tracks.count)
129
+ }.not_to repeatedly_load('Track')
130
+ ```
131
+
132
+ ## Counting Queries
133
+
134
+ ### Types of Comparisons
135
+
136
+ Several comparison types are available, along with some aliases to allow for
137
+ easier to read tests.
138
+
139
+ ```ruby
140
+ expect {}.to execute.less_than(20).queries
97
141
  expect {}.to execute.fewer_than(20).queries
98
- expect {}.to execute.less_than(20).queries # alias for fewer_than
142
+
143
+ expect {}.to execute.less_than_or_equal_to(20).queries
144
+ expect {}.to execute.at_most(20).queries
145
+
146
+ expect {}.to execute.greater_than(20).queries
147
+ expect {}.to execute.more_than(20).queries
148
+
149
+ expect {}.to execute.greater_than_or_equal_to(20).queries
150
+ expect {}.to execute.at_least(20).queries
151
+
152
+ expect {}.to execute.exactly(20).queries
153
+
154
+ expect {}.to execute.at_least(2).queries
155
+ expect {}.to execute.at_least(1).query # singular form also accepted
156
+ ```
157
+
158
+ ### Specific Query Types
159
+
160
+ You can of course make assertions for the total number of queries executed, but
161
+ sometimes it's more valuable to assert particular _types_ of queries, such as
162
+ inserts or find statements. Matchers are supported for this as well!
163
+
164
+ **Note:** Transaction (for example, `ROLLBACK`) queries are not counted in any of these
165
+ categories, nor are queries that load the DB schema.
166
+
167
+ **Note:** Destroy and delete queries are both condensed into the matcher for
168
+ `destroy_queries`.
169
+
170
+ ```ruby
171
+ expect {}.to execute.exactly(20).queries
172
+
173
+ expect {}.to execute.exactly(20).insert_queries
174
+ expect {}.to execute.exactly(20).load_queries
175
+ expect {}.to execute.exactly(20).destroy_queries
176
+ expect {}.to execute.exactly(20).exists_queries
177
+
178
+ expect {}.to execute.exactly(20).schema_queries
179
+ expect {}.to execute.exactly(20).transaction_queries
99
180
  ```
100
181
 
101
182
  ## Future Planned Functionality
@@ -103,17 +184,11 @@ expect {}.to execute.less_than(20).queries # alias for fewer_than
103
184
  This gem still has lots of future functionality. See below.
104
185
 
105
186
  ```ruby
106
- expect {}.to execute.more_than(20).activerecord_queries
107
- expect {}.to execute.fewer_than(20).insert_queries
108
- expect {}.to execute.exactly(5).queries
109
- expect {}.to execute.at_least(5).handrolled_queries
110
-
111
- expect {}.to execute.less_than(20).delete_queries
112
- expect {}.to execute.less_than(20).load_queries
113
- expect {}.to execute.less_than(20).schema_queries
114
- expect {}.to execute.less_than(20).exists_queries
115
- expect {}.to execute.less_than(20).queries
116
- expect {}.to execute.less_than(20).queries_of_type("Audited::Audit Load")
187
+ expect {}.to execute.at_least(2).queries_of_type("Audited::Audit Load")
188
+ expect {}.to execute.at_least(2).load_queries("Audited::Audit")
189
+
190
+ expect {}.to execute.at_least(2).activerecord_queries
191
+ expect {}.to execute.at_least(2).hand_rolled_queries
117
192
 
118
193
  expect {}.not_to rollback_transaction.exactly(5).times
119
194
  expect {}.not_to commit_transaction.once
@@ -123,18 +198,10 @@ expect {}.to create.exactly(5).of_type(User)
123
198
  expect {}.to insert.exactly(5).subscription_changes
124
199
  expect {}.to update.exactly(2).of_any_type
125
200
  expect {}.to delete.exactly(2).of_any_type
126
-
127
- expect {}.not_to repeatedly_load(Audited::Audit)
128
-
129
- at_least, more_than, at_most, less_than, lteq?
130
- exactly(1) => once?
131
201
  ```
132
202
 
133
- - ignore transactionals (begin / rollback)
134
- - `name: Foo Load`
135
- - differentiate AR queries from generic ones? arbitrary execution somehow?
136
- - warn about warmup
137
- - make sure we don't smite any built in methods (or from other libs)
203
+ - warn if we smite any built in methods (or methods from other libs)
204
+ - support Rails 6 bulk insert (still one query)
138
205
 
139
206
  ## Development
140
207
 
@@ -1,23 +1,42 @@
1
1
  module RSpec::ActiveRecord::Expectations
2
2
  class Collector
3
3
  def initialize
4
- @counts = {
5
- queries: 0
6
- }
4
+ @inspector = QueryInspector.new
5
+ @by_name = {}
6
+ @counts = QueryInspector.valid_query_types.each_with_object({}) do |query_type, hash|
7
+ hash[query_type] = 0
8
+ end
7
9
 
8
- ActiveSupport::Notifications.subscribe("sql.active_record", method(:record_query))
10
+ @subscription = ActiveSupport::Notifications.subscribe("sql.active_record", method(:record_query))
11
+ end
12
+
13
+ def finalize
14
+ ActiveSupport::Notifications.unsubscribe(@subscription)
9
15
  end
10
16
 
11
17
  def queries_of_type(type)
12
- @counts.fetch(type)
18
+ @counts[type] || (raise ArgumentError, "Sorry, #{type} is not a valid kind of query")
13
19
  end
14
20
 
15
21
  def valid_type?(type)
16
22
  @counts.include? type
17
23
  end
18
24
 
25
+ def calls_by_name(name)
26
+ @by_name.fetch(name, 0)
27
+ end
28
+
19
29
  def record_query(*_unused, data)
20
- @counts[:queries] += 1
30
+ categories = @inspector.categorize(data)
31
+
32
+ categories.each do |category|
33
+ @counts[category] += 1
34
+ rescue NoMethodError
35
+ raise "tried to add to to #{category} but it doesn't exist"
36
+ end
37
+
38
+ @by_name[data[:name]] ||= 0
39
+ @by_name[data[:name]] += 1
21
40
  end
22
41
  end
23
42
  end
@@ -0,0 +1,29 @@
1
+ module RSpec::ActiveRecord::Expectations
2
+ module Matchers
3
+ class LoadMatcher
4
+ def initialize(klass)
5
+ @collector = Collector.new
6
+ @klass = klass.to_s
7
+ end
8
+
9
+ def supports_block_expectations?
10
+ true
11
+ end
12
+
13
+ def matches?(block)
14
+ block.call
15
+
16
+ @count = @collector.calls_by_name("#{@klass} Load")
17
+ @count > 1
18
+ end
19
+
20
+ def failure_message
21
+ "expected block to repeatedly load #{@klass}, but it was loaded #{@count} times"
22
+ end
23
+
24
+ def failure_message_when_negated
25
+ "expected block not to repeatedly load #{@klass}, but it was loaded #{@count} times"
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,141 @@
1
+ module RSpec::ActiveRecord::Expectations
2
+ module Matchers
3
+ class QueryCountMatcher
4
+ attr_reader :failure_message, :failure_message_when_negated
5
+
6
+ def initialize
7
+ @collector = Collector.new
8
+
9
+ @match_method = nil
10
+ @comparison = nil
11
+ @query_type = nil
12
+ end
13
+
14
+ def supports_block_expectations?
15
+ true
16
+ end
17
+
18
+ def matches?(block)
19
+ raise NoComparisonError unless @match_method
20
+ raise NoQueryTypeError unless @collector.valid_type?(@query_type)
21
+
22
+ block.call
23
+ result = @match_method.call
24
+ @collector.finalize
25
+
26
+ result
27
+ end
28
+
29
+ # COMPARISON TYPES
30
+
31
+ def less_than(n)
32
+ @comparison = n
33
+ @match_method = method(:compare_less_than)
34
+ self
35
+ end
36
+ alias_method :fewer_than, :less_than
37
+
38
+ def less_than_or_equal_to(n)
39
+ @comparison = n
40
+ @match_method = method(:compare_less_than_or_equal_to)
41
+ self
42
+ end
43
+ alias_method :at_most, :less_than_or_equal_to
44
+
45
+ def greater_than(n)
46
+ @comparison = n
47
+ @match_method = method(:compare_greater_than)
48
+ self
49
+ end
50
+ alias_method :more_than, :greater_than
51
+
52
+ def greater_than_or_equal_to(n)
53
+ @comparison = n
54
+ @match_method = method(:compare_greater_than_or_equal_to)
55
+ self
56
+ end
57
+ alias_method :at_least, :greater_than_or_equal_to
58
+
59
+ def exactly(n)
60
+ @comparison = n
61
+ @match_method = method(:compare_exactly)
62
+ self
63
+ end
64
+
65
+ # TARGET QUERY TYPES
66
+
67
+ RSpec::ActiveRecord::Expectations::QueryInspector.valid_query_types.each do |type|
68
+ define_method type do
69
+ @query_type = type
70
+ self
71
+ end
72
+
73
+ singularized_type = type.to_s.gsub('queries', 'query')
74
+ if singularized_type != type.to_s
75
+ define_method singularized_type do
76
+ @query_type = type
77
+ self
78
+ end
79
+ end
80
+ end
81
+
82
+ # TODO singularize everything
83
+ alias_method :query, :queries
84
+
85
+ private
86
+
87
+ def humanized_query_type
88
+ @query_type.to_s.gsub("_", " ")
89
+ end
90
+
91
+ # MATCHERS
92
+
93
+ def compare_less_than
94
+ count = @collector.queries_of_type(@query_type)
95
+
96
+ @failure_message = "expected block to execute fewer than #{@comparison} #{humanized_query_type}, but it executed #{count}"
97
+ @failure_message_when_negated = "expected block not to execute fewer than #{@comparison} #{humanized_query_type}, but it executed #{count}"
98
+
99
+ count < @comparison
100
+ end
101
+
102
+ def compare_less_than_or_equal_to
103
+ count = @collector.queries_of_type(@query_type)
104
+
105
+ # boy this negated operator is confusing. don't use that plz.
106
+ @failure_message = "expected block to execute at most #{@comparison} #{humanized_query_type}, but it executed #{count}"
107
+ @failure_message_when_negated = "expected block not to execute any less than #{@comparison} #{humanized_query_type}, but it executed #{count}"
108
+
109
+ count <= @comparison
110
+ end
111
+
112
+ def compare_greater_than
113
+ count = @collector.queries_of_type(@query_type)
114
+
115
+ @failure_message = "expected block to execute greater than #{@comparison} #{humanized_query_type}, but it executed #{count}"
116
+ @failure_message_when_negated = "expected block not to execute greater than #{@comparison} #{humanized_query_type}, but it executed #{count}"
117
+
118
+ count > @comparison
119
+ end
120
+
121
+ def compare_greater_than_or_equal_to
122
+ count = @collector.queries_of_type(@query_type)
123
+
124
+ # see above, negating this matcher is so confusing.
125
+ @failure_message = "expected block to execute at least #{@comparison} #{humanized_query_type}, but it executed #{count}"
126
+ @failure_message_when_negated = "expected block not to execute any more than #{@comparison} #{humanized_query_type}, but it executed #{count}"
127
+
128
+ count >= @comparison
129
+ end
130
+
131
+ def compare_exactly
132
+ count = @collector.queries_of_type(@query_type)
133
+
134
+ @failure_message = "expected block to execute exactly #{@comparison} #{humanized_query_type}, but it executed #{count}"
135
+ @failure_message_when_negated = "expected block not to execute exactly #{@comparison} #{humanized_query_type}, but it executed #{count}"
136
+
137
+ count == @comparison
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,28 @@
1
+ module RSpec::ActiveRecord::Expectations
2
+ class QueryInspector
3
+ def self.valid_query_types
4
+ [:queries, :schema_queries, :transaction_queries, :insert_queries,
5
+ :load_queries, :destroy_queries, :exists_queries]
6
+ end
7
+
8
+ def categorize(query)
9
+ if query[:name] == "SCHEMA"
10
+ [:schema_queries]
11
+ elsif query[:name] == "TRANSACTION" || query[:sql] =~ /^begin/i || query[:sql] =~ /^commit/i
12
+ [:transaction_queries]
13
+ elsif query[:name] =~ /Create$/
14
+ [:queries, :insert_queries]
15
+ elsif query[:name] =~ /Load$/
16
+ [:queries, :load_queries]
17
+ elsif query[:name] =~ /Destroy$/
18
+ [:queries, :destroy_queries]
19
+ elsif query[:name] =~ /Delete All$/
20
+ [:queries, :destroy_queries]
21
+ elsif query[:name] =~ /Exists\??$/
22
+ [:queries, :exists_queries]
23
+ else
24
+ [:queries]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,10 +4,16 @@ module RSpec
4
4
  def execute
5
5
  Matchers::QueryCountMatcher.new
6
6
  end
7
+
8
+ def repeatedly_load(klass)
9
+ Matchers::LoadMatcher.new(klass)
10
+ end
7
11
  end
8
12
  end
9
13
  end
10
14
 
11
15
  require_relative 'expectations/errors'
16
+ require_relative 'expectations/query_inspector'
12
17
  require_relative 'expectations/collector'
13
- require_relative 'expectations/matchers/query_count'
18
+ require_relative 'expectations/matchers/query_count_matcher'
19
+ require_relative 'expectations/matchers/load_matcher'
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "rspec-activerecord-expectations"
3
- spec.version = '1.0.1'
3
+ spec.version = '2.1.0'
4
4
  spec.authors = ["Joseph Mastey"]
5
5
  spec.email = ["hello@joemastey.com"]
6
6
 
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.description = %q{Adds new matchers to rspec to help you test whether your code is executing an unreasonable number of queries.}
9
9
  spec.homepage = "https://github.com/jmmastey/rspec-activerecord-expectations"
10
10
  spec.license = "MIT"
11
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
11
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
12
12
 
13
13
  spec.metadata["homepage_uri"] = spec.homepage
14
14
  spec.metadata["source_code_uri"] = spec.homepage
@@ -23,7 +23,12 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "activerecord", ">= 5.0.0", "< 7.1.0"
26
- spec.add_dependency "sqlite3", "~> 1.0"
26
+
27
+ if RUBY_PLATFORM == 'java'
28
+ spec.add_development_dependency "activerecord-jdbcsqlite3-adapter", '>= 60'
29
+ else
30
+ spec.add_development_dependency "sqlite3", "~> 1.0"
31
+ end
27
32
 
28
33
  spec.add_development_dependency "pry", "~> 0.0"
29
34
  spec.add_development_dependency "appraisal", "~> 2"
metadata CHANGED
@@ -1,17 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-activerecord-expectations
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.1.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-30 00:00:00.000000000 Z
11
+ date: 2022-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activerecord
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
@@ -20,8 +19,9 @@ dependencies:
20
19
  - - "<"
21
20
  - !ruby/object:Gem::Version
22
21
  version: 7.1.0
23
- type: :runtime
22
+ name: activerecord
24
23
  prerelease: false
24
+ type: :runtime
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
@@ -31,42 +31,42 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: 7.1.0
33
33
  - !ruby/object:Gem::Dependency
34
- name: sqlite3
35
34
  requirement: !ruby/object:Gem::Requirement
36
35
  requirements:
37
- - - "~>"
36
+ - - ">="
38
37
  - !ruby/object:Gem::Version
39
- version: '1.0'
40
- type: :runtime
38
+ version: '60'
39
+ name: activerecord-jdbcsqlite3-adapter
41
40
  prerelease: false
41
+ type: :development
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "~>"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '1.0'
46
+ version: '60'
47
47
  - !ruby/object:Gem::Dependency
48
- name: pry
49
48
  requirement: !ruby/object:Gem::Requirement
50
49
  requirements:
51
50
  - - "~>"
52
51
  - !ruby/object:Gem::Version
53
52
  version: '0.0'
54
- type: :development
53
+ name: pry
55
54
  prerelease: false
55
+ type: :development
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0.0'
61
61
  - !ruby/object:Gem::Dependency
62
- name: appraisal
63
62
  requirement: !ruby/object:Gem::Requirement
64
63
  requirements:
65
64
  - - "~>"
66
65
  - !ruby/object:Gem::Version
67
66
  version: '2'
68
- type: :development
67
+ name: appraisal
69
68
  prerelease: false
69
+ type: :development
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
@@ -102,7 +102,9 @@ files:
102
102
  - lib/rspec/activerecord/expectations.rb
103
103
  - lib/rspec/activerecord/expectations/collector.rb
104
104
  - lib/rspec/activerecord/expectations/errors.rb
105
- - lib/rspec/activerecord/expectations/matchers/query_count.rb
105
+ - lib/rspec/activerecord/expectations/matchers/load_matcher.rb
106
+ - lib/rspec/activerecord/expectations/matchers/query_count_matcher.rb
107
+ - lib/rspec/activerecord/expectations/query_inspector.rb
106
108
  - rspec-activerecord-expectations.gemspec
107
109
  homepage: https://github.com/jmmastey/rspec-activerecord-expectations
108
110
  licenses:
@@ -119,14 +121,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
121
  requirements:
120
122
  - - ">="
121
123
  - !ruby/object:Gem::Version
122
- version: 2.3.0
124
+ version: 2.5.0
123
125
  required_rubygems_version: !ruby/object:Gem::Requirement
124
126
  requirements:
125
127
  - - ">="
126
128
  - !ruby/object:Gem::Version
127
129
  version: '0'
128
130
  requirements: []
129
- rubygems_version: 3.1.6
131
+ rubygems_version: 3.2.29
130
132
  signing_key:
131
133
  specification_version: 4
132
134
  summary: A gem to test how many activerecord queries your code executes.
@@ -1,57 +0,0 @@
1
- module RSpec::ActiveRecord::Expectations
2
- module Matchers
3
- class QueryCountMatcher
4
- attr_reader :failure_message, :failure_message_when_negated
5
-
6
- def initialize
7
- @collector = Collector.new
8
-
9
- @match_method = nil
10
- @comparison = nil
11
- @query_type = nil
12
- end
13
-
14
- def supports_block_expectations?
15
- true
16
- end
17
-
18
- def matches?(block)
19
- raise NoComparisonError unless @match_method
20
- raise NoQueryTypeError unless @collector.valid_type?(@query_type)
21
-
22
- result = block.call
23
-
24
- !!@match_method.call
25
- end
26
-
27
- # COMPARISON TYPES
28
-
29
- def fewer_than(n)
30
- @comparison = n
31
- @match_method = method(:match_fewer_than)
32
- self
33
- end
34
- alias_method :less_than, :fewer_than
35
-
36
- # TARGET QUERY TYPES
37
-
38
- def queries
39
- @query_type = :queries
40
- self
41
- end
42
-
43
- private
44
-
45
- # MATCHERS
46
-
47
- def match_fewer_than
48
- count = @collector.queries_of_type(@query_type)
49
-
50
- @failure_message = "expected block to execute fewer than #{@comparison} queries, but it executed #{count}"
51
- @failure_message_when_negated = "expected block not to execute fewer than #{@comparison} queries, but it executed #{count}"
52
-
53
- count < @comparison
54
- end
55
- end
56
- end
57
- end