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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ed8bce8c2576663b3d187efc7ae064c239c9ab8f3e6dacae592563ea4c484fb
4
- data.tar.gz: 9e67c875fd8dcab13a8e0ed56b34f842519f1af4f0037f5c8955970cc82f2850
3
+ metadata.gz: ea0eb161965acaf677cec0de83466eece5379423903fc0a04b181cabe61a8121
4
+ data.tar.gz: 4df14e9211baf4ac6f3935a68b910191480f6f6af622f36c7d7e51a90374d222
5
5
  SHA512:
6
- metadata.gz: 0ea389afd2110fbaca8c2215507874e1fed2ad1e1f5dae167baaf532d56f91bcfa3f7458a88a71e6ce2de341160ba0fe3f3a25c786641204ebda1f3fe2db707c
7
- data.tar.gz: 9ace14690c79ee0ca1e5c9a3841a9769d58b315685e811b253d393c2a5858294153cf1b0e88471b584112391b351173163cd4d6326920654e35d3aac83c6cf77
6
+ metadata.gz: 75bd827d5d0fc6566ba54f48cd432fab6cad301f2b5eb781383ea227ec74e2699733026fc22086899ac8bf725280e9cb1a5d7ca42545074cee1eb932142f9d93
7
+ data.tar.gz: ad9f387210fb8d30c06b5177a51b934a415d36805d94729d8117408200b241ee3f9408884bfbe63ab2bc93b28118f69a13dbe1aa05e3a2eb80bf04705a6b3de4
@@ -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: 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
@@ -26,7 +26,7 @@ jobs:
26
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,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: ${{ matrix.os }}
48
- name: Test Legacy ruby ${{ matrix.ruby }} / rails ${{ matrix.rails }} / ${{ matrix.os }}
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 correct gems / rails version
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, greater_than
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
- ## Supported Matchers
94
+ ## Counting Queries
95
95
 
96
- Listed along with their aliases.
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
- - make sure we don't smite any built in methods (or from other libs)
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
- @counts = {
5
- queries: 0
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.fetch(type)
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
- @counts[:queries] += 1
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
- def queries
60
- @query_type = :queries
61
- self
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
@@ -9,5 +9,6 @@ module RSpec
9
9
  end
10
10
 
11
11
  require_relative 'expectations/errors'
12
+ require_relative 'expectations/query_inspector'
12
13
  require_relative 'expectations/collector'
13
14
  require_relative 'expectations/matchers/query_count'
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "rspec-activerecord-expectations"
3
- spec.version = '1.1.0'
3
+ spec.version = '1.2.0'
4
4
  spec.authors = ["Joseph Mastey"]
5
5
  spec.email = ["hello@joemastey.com"]
6
6
 
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.1.0
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-30 00:00:00.000000000 Z
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: