Skip to content

Commit

Permalink
Allow SELECT queries without a WHERE or LIMIT to be tested with the u…
Browse files Browse the repository at this point in the history
…nscoped option
  • Loading branch information
stevehodges committed Sep 23, 2019
1 parent 3cb1bf5 commit a752ea3
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ describe 'MyCode' do
end
end

context 'when we only care about unscoped queries (SELECT without a WHERE or LIMIT clause))' do
it 'makes an unscoped database query' do
expect { subject.make_one_query }.to make_database_queries(unscoped: true)
end
end

context 'when we only care about queries matching a certain pattern' do
it 'makes a destructive database query' do
expect { subject.make_special_queries }.to make_database_queries(matching: 'DELETE * FROM')
Expand Down
6 changes: 6 additions & 0 deletions lib/db_query_matchers/make_database_queries.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
# @example
# expect { subject }.to make_database_queries(manipulative: true)
#
# @example
# expect { subject }.to make_database_queries(unscoped: true)
#
# @see DBQueryMatchers::QueryCounter
RSpec::Matchers.define :make_database_queries do |options = {}|
if RSpec::Core::Version::STRING =~ /^2/
Expand Down Expand Up @@ -46,6 +49,9 @@ def pluralize(count, singular, plural = nil)
if options[:manipulative]
counter_options[:matches] = [/^\ *(INSERT|UPDATE|DELETE\ FROM)/]
end
if options[:unscoped]
counter_options[:matches] = [/^ SELECT(?!\sCOUNT).*FROM(?!.*(WHERE|LIMIT))/mx]
end
if options[:matching]
counter_options[:matches] ||= []
case options[:matching]
Expand Down
44 changes: 44 additions & 0 deletions spec/db_query_matchers/make_database_queries_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,50 @@
end
end

context 'when a `unscoped` option is as true' do
shared_examples 'it raises an error' do
it 'raises an error' do
expect do
expect { subject }.to make_database_queries(unscoped: true)
end.to raise_error(RSpec::Expectations::ExpectationNotMetError,
/expected queries, but none were made/)
end

it 'does not raise with `to_not`' do
expect { subject }.to_not make_database_queries(unscoped: true)
end
end

before do
Cat.create if Cat.count == 0
end

context 'and there is a query without a WHERE or LIMIT clause' do
subject { Cat.all.to_a }

it 'matches true' do
expect { subject }.to make_database_queries(unscoped: true)
end

it 'raises an error with `to_not`' do
expect do
expect { subject }.to_not make_database_queries(unscoped: true)
end.to raise_error(RSpec::Expectations::ExpectationNotMetError,
/expected no queries, but 1 were made/)
end
end

context 'there is a limit clause' do
subject { Cat.all.limit(100).to_a }
include_examples 'it raises an error'
end

context 'there is a where clause' do
subject { Cat.where(name: 'bob').to_a }
include_examples 'it raises an error'
end
end

context 'when a `matching` option is specified' do
context 'with a string matcher' do
context 'and there is a query matching the matcher specified' do
Expand Down

0 comments on commit a752ea3

Please sign in to comment.