rspec-activerecord-expectations 1.1.0 → 1.2.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: 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: