ar-query-matchers 0.7.0 → 0.8.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: e73f1af783ac0aea8a1342b20e01d139106e29c2c4048bf3d30086a13675f204
4
- data.tar.gz: 64b309608ae8f52ba8d7a998ea0e7658eebb2ee7d11122d8e1c0934f042131b6
3
+ metadata.gz: 2bbbb0ab94d0e842a364dbe7d970900fa6bcdf2b6d9d3a0a2eb3cfac96df9efd
4
+ data.tar.gz: 6650c24207bd4a7d47077ec311b05530eab74dca5b097537ca554023f8cd92ce
5
5
  SHA512:
6
- metadata.gz: 13b5fe44e89c7e0df944882d4d15dac2ff72b8fe3a679591c46b15015587159246c4e2344d2e604b6a31a0ee6dc5a450eacd85ef638d90d578f1b4073fca2f58
7
- data.tar.gz: 61d48528375466023a71bf17ad2e453ec62ce5520f43200f88de94ff2f116522be3694fe2c0116f83093fa5f1087cf4774471143e63deb8f465dd03173bda8cd
6
+ metadata.gz: 1b548ed7b6d0d3ad9d144f2994846c84e087c420f5390cfe2ad957b3a598383c07576d5d51e5cb209bc589e928ad92fd7af56c1c40c73b198d510dab0721c50e
7
+ data.tar.gz: e27df0c699c8c2021d0e146f6070cba820226e2ca4dcc2258bcde3247356b4007600433cf928da00bda8585d1a32e8c638097ec95ecfa2e524db5e1194c4a5b4
data/CHANGELOG.md CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.8.0] - 2022-01-27
10
+ ### Added
11
+ - Changed the implementation of ArQueryMatchers::Queries::TableName to calculate distance of class name to table name to determine which class name is most likely. This changes how tables in `only_load_at_most_models` are calculated.
12
+
9
13
  ## [0.7.0] - 2022-01-27
10
14
  ### Added
11
15
  - A new matcher, `only_load_at_most_models`, will do a less-than-or-equal-to (<=) check on model counts. This is a method that makes tests less noisy as performance gets better.
data/README.md CHANGED
@@ -16,7 +16,7 @@ If you'd like to pick that up, please have a look at: https://github.com/Gusto/a
16
16
  Include it in your Gemfile:
17
17
  ```ruby
18
18
  group :test do
19
- gem 'ar-query-matchers', '~> 0.2.0', require: false
19
+ gem 'ar-query-matchers', '~> 0.7.0', require: false
20
20
  end
21
21
  ```
22
22
 
@@ -40,9 +40,10 @@ This gem defines a few categories of matchers:
40
40
  - **Update**: Which models are updated during a block
41
41
 
42
42
  Each matcher category includes 3 assertions, for example, for the Load category, you could use the following assertions:
43
- - **only_load_models**: Strict assertion, not other query is allowed.
43
+ - **only_load_models**: Strict assertion of both models loaded and query counts. No other query is allowed.
44
+ - **only_load_at_most_models**: Strict assertion of models loaded, with an upper bound on the number of queries allowed against each.
44
45
  - **not_load_models**: No models are allowed to be loaded.
45
- - **load_models**: Inclusion, other models are allowed to be loaded if not specified in the assertion.
46
+ - **load_models**: Inclusion. Other models are allowed to be loaded if not specified in the assertion.
46
47
 
47
48
 
48
49
  **For example:**
@@ -58,6 +59,17 @@ expect { some_code() }.to only_load_models(
58
59
  )
59
60
  ```
60
61
 
62
+ The following spec will pass only if there are 4 or less SQL SELECTs that
63
+ load User records (and 1 or less for both Address and Payroll respectively) _and_ no other models
64
+ perform any SELECT queries.
65
+ ```ruby
66
+ expect { some_code() }.to only_load_at_most_models(
67
+ 'User' => 4,
68
+ 'Address' => 1,
69
+ 'Payroll' => 1,
70
+ )
71
+ ```
72
+
61
73
  The following spec will pass only if there are no select queries.
62
74
  ```ruby
63
75
  expect { some_code() }.to not_load_models
@@ -17,7 +17,7 @@ module ArQueryMatchers
17
17
  class CreateQueryFilter < QueryFilter
18
18
  # Matches unnamed SQL operations like the following:
19
19
  # "INSERT INTO `company_approval_details` ..."
20
- TABLE_NAME_SQL_PATTERN = /INSERT INTO [`"](?<table_name>[^`"]+)[`"]/.freeze
20
+ TABLE_NAME_SQL_PATTERN = /INSERT INTO [`"](?<table_name>[^`"]+)[`"]/
21
21
 
22
22
  def filter_map(_name, sql)
23
23
  # for inserts, name is always 'SQL', we have to rely on pattern matching the query string.
@@ -17,11 +17,11 @@ module ArQueryMatchers
17
17
  class LoadQueryFilter < Queries::QueryFilter
18
18
  # Matches named SQL operations like the following:
19
19
  # 'User Load'
20
- MODEL_LOAD_PATTERN = /\A(?<model_name>[\w:]+) (Load|Exists)\Z/.freeze
20
+ MODEL_LOAD_PATTERN = /\A(?<model_name>[\w:]+) (Load|Exists)\Z/
21
21
 
22
22
  # Matches unnamed SQL operations like the following:
23
23
  # "SELECT COUNT(*) FROM `users` ..."
24
- MODEL_SQL_PATTERN = /SELECT (?:(?!SELECT).)* FROM [`"](?<table_name>[^`"]+)[`"]/.freeze
24
+ MODEL_SQL_PATTERN = /SELECT (?:(?!SELECT).)* FROM [`"](?<table_name>[^`"]+)[`"]/
25
25
 
26
26
  def filter_map(name, sql)
27
27
  # First check for a `SELECT * FROM` query that ActiveRecord has
@@ -71,7 +71,7 @@ module ArQueryMatchers
71
71
 
72
72
  # The 'marginalia' gem adds a line from the backtrace to the SQL query in
73
73
  # the form of a comment.
74
- MARGINALIA_SQL_COMMENT_PATTERN = %r{/*line:(?<line>.*)'*/}.freeze
74
+ MARGINALIA_SQL_COMMENT_PATTERN = %r{/*line:(?<line>.*)'*/}
75
75
  private_constant :MARGINALIA_SQL_COMMENT_PATTERN
76
76
 
77
77
  def to_proc(queries)
@@ -31,9 +31,9 @@ module ArQueryMatchers
31
31
  # { 'users' => [User, AtoUser],
32
32
  # 'employees => [Employee, PandaFlows::StateFields] }
33
33
 
34
- # Of all the models that share the same table name sort them by their
35
- # relative ancestry and pick the one that all the rest inherit from
36
- tables[table_name].min_by { |a, b| a.ancestors.include?(b) }
34
+ # Pick the class with the shortest distance to the table name
35
+ ideal_class_name = table_name.classify
36
+ tables[table_name].min_by { |a| DidYouMean::Levenshtein.distance(ideal_class_name, a.to_s) }
37
37
  end
38
38
  end
39
39
  end
@@ -17,7 +17,7 @@ module ArQueryMatchers
17
17
  class UpdateQueryFilter < QueryFilter
18
18
  # Matches unnamed SQL operations like the following:
19
19
  # "UPDATE `bank_account_verifications` ..."
20
- TABLE_NAME_SQL_PATTERN = /UPDATE [`"](?<table_name>[^`"]+)[`"]/.freeze
20
+ TABLE_NAME_SQL_PATTERN = /UPDATE [`"](?<table_name>[^`"]+)[`"]/
21
21
 
22
22
  def filter_map(_name, sql)
23
23
  # for updates, name is always 'SQL', we have to rely on pattern matching on the query string instead.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-query-matchers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matan Zruya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-28 00:00:00.000000000 Z
11
+ date: 2023-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -192,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
192
  - !ruby/object:Gem::Version
193
193
  version: '0'
194
194
  requirements: []
195
- rubygems_version: 3.0.3.1
195
+ rubygems_version: 3.4.10
196
196
  signing_key:
197
197
  specification_version: 4
198
198
  summary: Ruby test matchers for instrumenting ActiveRecord query counts