Skip to content

Commit dc0de2c

Browse files
authored
Merge pull request #2 from openfoodfoundation/summary-stats
Add query summary matching
2 parents b3a6238 + db75acb commit dc0de2c

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ expect { nil }.to_not query_database
2222
expect { User.last }.to query_database 1
2323
expect { User.create }.to query_database 3.times
2424

25-
# Assert specific queries:
25+
# Assert a specific query list:
2626
expect { User.last }.to query_database ["User Load"]
2727

2828
expect { User.create!.update(name: "Jane") }.to query_database [
@@ -33,6 +33,14 @@ expect { User.create!.update(name: "Jane") }.to query_database [
3333
"User Update",
3434
"TRANSACTION",
3535
]
36+
37+
# Assert a specific query summary:
38+
expect { User.create!.update(name: "Jane") }.to query_database(
39+
{
40+
insert: { users: 1 },
41+
update: { users: 1 },
42+
}
43+
)
3644
```
3745

3846
## Alternatives

lib/rspec/sql.rb

+8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
require "active_support"
44
require "rspec"
55

6+
require_relative "sql/query_summary"
7+
68
module RSpec
79
module Sql; end
810

@@ -18,6 +20,8 @@ module Sql; end
1820
@queries.size == expected.size
1921
elsif expected.is_a?(Array)
2022
query_names == expected
23+
elsif expected.is_a?(Hash)
24+
query_summary == expected
2125
else
2226
raise "What are you expecting?"
2327
end
@@ -52,6 +56,10 @@ def query_descriptions
5256
@queries.map { |q| "#{q[:name]} #{q[:sql]}" }
5357
end
5458

59+
def query_summary
60+
Sql::QuerySummary.new(@queries).summary
61+
end
62+
5563
def scribe_queries(&)
5664
queries = []
5765

lib/rspec/sql/query_summary.rb

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
module RSpec
4+
module Sql
5+
class QuerySummary
6+
QUERY_TYPES = [:delete, :insert, :select, :update].freeze
7+
8+
attr_reader :summary
9+
10+
def initialize(queries)
11+
@summary = {}
12+
queries.each do |payload|
13+
type = get_type(payload[:sql])
14+
next if QUERY_TYPES.exclude?(type) || pg_query?(payload[:sql])
15+
16+
table = get_table(payload[:sql])
17+
@summary[type] ||= {}
18+
@summary[type][table] ||= 0
19+
@summary[type][table] += 1
20+
end
21+
end
22+
23+
private
24+
25+
def get_table(sql)
26+
sql_parts = sql.split
27+
case get_type(sql)
28+
when :insert
29+
sql_parts[2]
30+
when :update
31+
sql_parts[1]
32+
else
33+
table_index = sql_parts.index("FROM")
34+
sql_parts[table_index + 1]
35+
end.gsub(/(\\|")/, "").to_sym
36+
end
37+
38+
def get_type(sql)
39+
sql.split[0].downcase.to_sym
40+
end
41+
42+
def pg_query?(sql)
43+
sql.include?("SELECT a.attname") || sql.include?("pg_attribute")
44+
end
45+
end
46+
end
47+
end

rspec-sql.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Gem::Specification.new do |s|
33
s.version = "0.0.0"
44
s.summary = "RSpec::Sql matcher"
55
s.description = "RSpec matcher for database queries."
6-
s.authors = ["Maikel Linke"]
6+
s.authors = ["Maikel Linke", "Open Food Network contributors"]
77
s.email = "[email protected]"
88
s.files = Dir["lib/**/*.rb"]
99
s.homepage = "https://github.com/openfoodfoundation/rspec-sql"

spec/lib/rspec/sql_spec.rb

+9
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,13 @@
5757
"TRANSACTION",
5858
]
5959
end
60+
61+
it "expects a summary of queries" do
62+
expect { User.create!.update(name: "Jane") }.to query_database(
63+
{
64+
insert: { users: 1 },
65+
update: { users: 1 },
66+
}
67+
)
68+
end
6069
end

0 commit comments

Comments
 (0)