rspec-sql 0.0.1 → 0.0.3

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: 604f3e80d1493fef761a5cd6c4cc1f2b16ddeaea989fd06a52f6e5266c30a015
4
- data.tar.gz: caf7ab6da1bb00e2c49fae1be3ca2ed8c787adab7f3983e02ac0972f410f1140
3
+ metadata.gz: 9cfbb9dfa6686fc934767248d98c65a3ffa0647f9674df74792ab344109b2899
4
+ data.tar.gz: 576dce207bae8bdb03585dc0234a898bf12d4b8e9e27f22f55817ce03babb4d8
5
5
  SHA512:
6
- metadata.gz: fecdb314d1af946b4c1d37807f25ece49c3d0ce2a969984c7d8ac9ec325afee4359021e3623792a85085c0c77e17f1510b568f7d43733eb0a12ee6151cf4e1bb
7
- data.tar.gz: 01afcbf7343a73735ade838e1b0c1991cd8d4b62d9d38a9e75fc5c66b34c3d1fd34b38b8a97d3ddb9b297781624237e250e1775012f2e2cb4451240d62e90a14
6
+ metadata.gz: 8d50829389362c678403a0ddaf982e44232aa2b884159f8928f07943b351ca00b015d48854e953f977ac6f5f3eefd6e47b168e2c732311e7187f677e97753ed5
7
+ data.tar.gz: aff99ef38190a45774eb0ada50daaba8f9182d2f89f3ebcdfb35ed3781210b4e19941b3bedcc5ef736c186474c6ccec41bd0c9149918e38c1c773087a3b9673d
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "query_summary"
4
+
5
+ module RSpec
6
+ module Sql
7
+ # Compares expectations with actual queries.
8
+ class QueryMatcher
9
+ attr_reader :expected
10
+
11
+ def initialize(queries, expected)
12
+ @queries = queries
13
+ @expected = sanitize_number(expected)
14
+ end
15
+
16
+ def matches?
17
+ # Simple presence validation.
18
+ return !@queries.empty? if expected.nil?
19
+
20
+ actual == expected
21
+ end
22
+
23
+ def actual
24
+ @actual ||= actual_compared_to_expected
25
+ end
26
+
27
+ private
28
+
29
+ # Support writing: `is_expected.to query_database 5.times`
30
+ def sanitize_number(expected)
31
+ if expected.is_a?(Enumerator) && expected.inspect.match?(/:times>$/)
32
+ expected.size
33
+ else
34
+ expected
35
+ end
36
+ end
37
+
38
+ def actual_compared_to_expected
39
+ case expected
40
+ when Integer
41
+ @queries.size
42
+ when Array
43
+ query_names
44
+ when Hash
45
+ query_summary
46
+ else
47
+ raise "What are you expecting?"
48
+ end
49
+ end
50
+
51
+ def query_names
52
+ @queries.map { |q| q[:name] || q[:sql].split.take(2).join(" ") }
53
+ end
54
+
55
+ def query_summary
56
+ QuerySummary.new(@queries).summary
57
+ end
58
+ end
59
+ end
60
+ end
@@ -2,8 +2,9 @@
2
2
 
3
3
  module RSpec
4
4
  module Sql
5
+ # Converts a list of queries into a summary hash.
5
6
  class QuerySummary
6
- QUERY_TYPES = [:delete, :insert, :select, :update].freeze
7
+ QUERY_TYPES = %i[delete insert select update].freeze
7
8
 
8
9
  attr_reader :summary
9
10
 
data/lib/rspec/sql.rb CHANGED
@@ -3,36 +3,33 @@
3
3
  require "active_support"
4
4
  require "rspec"
5
5
 
6
- require_relative "sql/query_summary"
6
+ require_relative "sql/query_matcher"
7
7
 
8
+ # We are building within the RSpec namespace for consistency and convenience.
9
+ # We are not part of the RSpec team though.
8
10
  module RSpec
11
+ # RSpec::Sql contains our code.
9
12
  module Sql; end
10
13
 
11
- RSpec::Matchers.define :query_database do |expected = nil|
14
+ Matchers.define :query_database do |expected = nil|
12
15
  match do |block|
13
16
  @queries = scribe_queries(&block)
17
+ @matcher = Sql::QueryMatcher.new(@queries, expected)
18
+ expected = matcher.expected
14
19
 
15
- if expected.nil?
16
- !@queries.empty?
17
- elsif expected.is_a?(Integer)
18
- @queries.size == expected
19
- elsif expected.is_a?(Enumerator) && expected.inspect.match?(/:times>$/)
20
- @queries.size == expected.size
21
- elsif expected.is_a?(Array)
22
- query_names == expected
23
- elsif expected.is_a?(Hash)
24
- query_summary == expected
25
- else
26
- raise "What are you expecting?"
27
- end
20
+ matcher.matches?
28
21
  end
29
22
 
30
23
  failure_message do |_block|
24
+ if expected.nil?
25
+ return "Expected at least one database query but observed none."
26
+ end
27
+
31
28
  <<~MESSAGE
32
29
  Expected database queries: #{expected}
33
- Actual database queries: #{query_names}
30
+ Actual database queries: #{matcher.actual}
34
31
 
35
- Diff: #{Expectations.differ.diff_as_object(query_names, expected)}
32
+ Diff: #{diff(matcher.actual, expected)}
36
33
 
37
34
  Full query log:
38
35
 
@@ -41,31 +38,40 @@ module RSpec
41
38
  end
42
39
 
43
40
  failure_message_when_negated do |_block|
44
- "Expected no database queries but observed:\n\n#{query_descriptions.join("\n")}"
41
+ <<~TXT
42
+ Expected no database queries but observed:
43
+
44
+ #{query_descriptions.join("\n")}
45
+ TXT
45
46
  end
46
47
 
47
48
  def supports_block_expectations?
48
49
  true
49
50
  end
50
51
 
51
- def query_names
52
- @queries.map { |q| q[:name] || q[:sql].split.take(2).join(" ") }
53
- end
54
-
55
52
  def query_descriptions
56
53
  @queries.map { |q| "#{q[:name]} #{q[:sql]}" }
57
54
  end
58
55
 
59
- def query_summary
60
- Sql::QuerySummary.new(@queries).summary
56
+ def matcher
57
+ @matcher
58
+ end
59
+
60
+ def diff(actual, expected)
61
+ if expected.is_a?(Numeric)
62
+ change = actual - expected
63
+ format("%+d", change)
64
+ else
65
+ Expectations.differ.diff_as_object(actual, expected)
66
+ end
61
67
  end
62
68
 
63
69
  def scribe_queries(&)
64
70
  queries = []
65
71
 
66
- logger = ->(_name, _started, _finished, _unique_id, payload) {
72
+ logger = lambda do |_name, _started, _finished, _unique_id, payload|
67
73
  queries << payload unless %w[CACHE SCHEMA].include?(payload[:name])
68
- }
74
+ end
69
75
 
70
76
  ActiveSupport::Notifications.subscribed(logger, "sql.active_record", &)
71
77
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maikel Linke
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-03-01 00:00:00.000000000 Z
12
+ date: 2024-04-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -46,11 +46,15 @@ extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
48
  - lib/rspec/sql.rb
49
+ - lib/rspec/sql/query_matcher.rb
49
50
  - lib/rspec/sql/query_summary.rb
50
51
  homepage: https://github.com/openfoodfoundation/rspec-sql
51
52
  licenses:
52
53
  - AGPL-3.0-or-later
53
- metadata: {}
54
+ metadata:
55
+ changelog_uri: https://github.com/openfoodfoundation/rspec-sql/releases
56
+ source_code_uri: https://github.com/openfoodfoundation/rspec-sql/
57
+ rubygems_mfa_required: 'true'
54
58
  post_install_message:
55
59
  rdoc_options: []
56
60
  require_paths: