Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add query summary matching #2

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ expect { nil }.to_not query_database
expect { User.last }.to query_database 1
expect { User.create }.to query_database 3.times

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

expect { User.create!.update(name: "Jane") }.to query_database [
Expand All @@ -33,6 +33,14 @@ expect { User.create!.update(name: "Jane") }.to query_database [
"User Update",
"TRANSACTION",
]

# Assert a specific query summary:
expect { User.create!.update(name: "Jane") }.to query_database(
{
insert: { users: 1 },
update: { users: 1 },
}
)
```

## Alternatives
Expand Down
8 changes: 8 additions & 0 deletions lib/rspec/sql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require "active_support"
require "rspec"

require_relative "sql/query_summary"

module RSpec
module Sql; end

Expand All @@ -18,6 +20,8 @@ module Sql; end
@queries.size == expected.size
elsif expected.is_a?(Array)
query_names == expected
elsif expected.is_a?(Hash)
query_summary == expected
else
raise "What are you expecting?"
end
Expand Down Expand Up @@ -52,6 +56,10 @@ def query_descriptions
@queries.map { |q| "#{q[:name]} #{q[:sql]}" }
end

def query_summary
Sql::QuerySummary.new(@queries).summary
end

def scribe_queries(&)
queries = []

Expand Down
47 changes: 47 additions & 0 deletions lib/rspec/sql/query_summary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module RSpec
module Sql
class QuerySummary
QUERY_TYPES = [:delete, :insert, :select, :update].freeze

attr_reader :summary

def initialize(queries)
@summary = {}
queries.each do |payload|
type = get_type(payload[:sql])
next if QUERY_TYPES.exclude?(type) || pg_query?(payload[:sql])

table = get_table(payload[:sql])
@summary[type] ||= {}
@summary[type][table] ||= 0
@summary[type][table] += 1
end
end

private

def get_table(sql)
sql_parts = sql.split
case get_type(sql)
when :insert
sql_parts[2]
when :update
sql_parts[1]
else
table_index = sql_parts.index("FROM")
sql_parts[table_index + 1]
end.gsub(/(\\|")/, "").to_sym
end

def get_type(sql)
sql.split[0].downcase.to_sym
end

def pg_query?(sql)
sql.include?("SELECT a.attname") || sql.include?("pg_attribute")
end
end
end
end
2 changes: 1 addition & 1 deletion rspec-sql.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Gem::Specification.new do |s|
s.version = "0.0.0"
s.summary = "RSpec::Sql matcher"
s.description = "RSpec matcher for database queries."
s.authors = ["Maikel Linke"]
s.authors = ["Maikel Linke", "Open Food Network contributors"]
s.email = "[email protected]"
s.files = Dir["lib/**/*.rb"]
s.homepage = "https://github.com/openfoodfoundation/rspec-sql"
Expand Down
9 changes: 9 additions & 0 deletions spec/lib/rspec/sql_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,13 @@
"TRANSACTION",
]
end

it "expects a summary of queries" do
expect { User.create!.update(name: "Jane") }.to query_database(
{
insert: { users: 1 },
update: { users: 1 },
}
)
end
end
Loading