From 84bf222cb2165bdfb079b79c1b6b039748431679 Mon Sep 17 00:00:00 2001 From: Steve Hodges Date: Tue, 24 Sep 2019 08:37:37 -0400 Subject: [PATCH] Unscoped option tests for UPDATE and DELETE queries, and INSERT queries copying from a table --- .../make_database_queries.rb | 11 +- .../make_database_queries_spec.rb | 154 ++++++++++++++++-- spec/spec_helper.rb | 4 + spec/support/models/cat.rb | 6 +- 4 files changed, 158 insertions(+), 17 deletions(-) diff --git a/lib/db_query_matchers/make_database_queries.rb b/lib/db_query_matchers/make_database_queries.rb index 4084c91..dec6b21 100644 --- a/lib/db_query_matchers/make_database_queries.rb +++ b/lib/db_query_matchers/make_database_queries.rb @@ -50,7 +50,16 @@ def pluralize(count, singular, plural = nil) counter_options[:matches] = [/^\ *(INSERT|UPDATE|DELETE\ FROM)/] end if options[:unscoped] - counter_options[:matches] = [/^ SELECT(?!\sCOUNT).*FROM(?!.*(WHERE|LIMIT))/mx] + counter_options[:matches] = [ + %r{ + (?: # Any of these appear + SELECT(?!\sCOUNT).*FROM| # SELECT ... FROM (not SELECT ... COUNT) + DELETE\sFROM| # DELETE ... FROM + UPDATE.*SET # UPDATE ... SET + ) + (?!.*(WHERE|LIMIT)) # Followed by WHERE and/or LIMIT + }mx # Ignore whitespace and newlines + ] end if options[:matching] counter_options[:matches] ||= [] diff --git a/spec/db_query_matchers/make_database_queries_spec.rb b/spec/db_query_matchers/make_database_queries_spec.rb index f7a01a5..b44fbe7 100644 --- a/spec/db_query_matchers/make_database_queries_spec.rb +++ b/spec/db_query_matchers/make_database_queries_spec.rb @@ -189,7 +189,7 @@ end end - context 'when a `unscoped` option is as true' do + context 'when a `unscoped` option is true' do shared_examples 'it raises an error' do it 'raises an error' do expect do @@ -208,28 +208,156 @@ end context 'and there is a query without a WHERE or LIMIT clause' do - subject { Cat.all.to_a } + context 'SELECT' do + subject { Cat.all.to_a } - it 'matches true' do - expect { subject }.to make_database_queries(unscoped: true) + 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 - 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/) + context 'DELETE' do + subject { Cat.delete_all } + + 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 'UPDATE' do + subject { Cat.update_all(name: 'Nombre') } + + 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 'INSERT' do + context 'without INTO SELECT' do + subject { Cat.create name: 'Joe' } + + it 'matches false' do + expect { subject }.to_not make_database_queries(unscoped: true) + end + end + + context 'with INTO SELECT' do + subject do + Cat.connection.execute <<-SQL + INSERT INTO "cats" SELECT * FROM "dogs"; + SQL + end + it 'matches true' do + expect { subject }.to make_database_queries(unscoped: true) + end + + it 'raises an error with `to`' 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 end end context 'there is a limit clause' do - subject { Cat.all.limit(100).to_a } - include_examples 'it raises an error' + context 'SELECT' do + subject { Cat.all.limit(100).to_a } + include_examples 'it raises an error' + end + + context 'UPDATE' do + subject { Cat.limit(10).update_all(name: 'Nombre') } + include_examples 'it raises an error' + end + + context 'DELETE' do + subject { Cat.limit(100).delete_all } + include_examples 'it raises an error' + end + + context 'INTO SELECT' do + subject do + Cat.connection.execute <<-SQL + INSERT INTO "cats" SELECT * FROM "dogs" LIMIT 100; + SQL + end + include_examples 'it raises an error' + end end context 'there is a where clause' do - subject { Cat.where(name: 'bob').to_a } - include_examples 'it raises an error' + context 'SELECT' do + subject { Cat.where(name: 'Bob').to_a } + include_examples 'it raises an error' + end + + context 'UPDATE' do + subject { Cat.where(name: 'Bob').update_all(name: 'Nombre') } + include_examples 'it raises an error' + end + + context 'DELETE' do + subject { Cat.where(name: 'Bob').delete_all } + include_examples 'it raises an error' + end + + context 'INTO SELECT' do + subject do + Cat.connection.execute <<-SQL + INSERT INTO "cats" SELECT * FROM "dogs" WHERE "dogs"."name" = 'Fido'; + SQL + end + include_examples 'it raises an error' + end + end + + context 'there is a where and limit clause' do + context 'SELECT' do + subject { Cat.where(name: 'Bob').limit(10).to_a } + include_examples 'it raises an error' + end + + context 'UPDATE' do + subject { Cat.where(name: 'Bob').limit(10).update_all(name: 'Nombre') } + include_examples 'it raises an error' + end + + context 'DELETE' do + subject { Cat.where(name: 'Bob').limit(10).delete_all } + include_examples 'it raises an error' + end + + context 'INTO SELECT' do + subject do + Cat.connection.execute <<-SQL + INSERT INTO "cats" SELECT * FROM "dogs" WHERE "dogs"."name" = 'Fido' LIMIT 10; + SQL + end + include_examples 'it raises an error' + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7845963..dace1cf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,5 +13,9 @@ create_table :cats, :force => true do |t| t.column :name, :string end + + create_table :dogs, :force => true do |t| + t.column :name, :string + end end end diff --git a/spec/support/models/cat.rb b/spec/support/models/cat.rb index 5aec8ca..bb46ac5 100644 --- a/spec/support/models/cat.rb +++ b/spec/support/models/cat.rb @@ -1,4 +1,4 @@ -# Test model -class Cat < ActiveRecord::Base +# Test models +class Cat < ActiveRecord::Base; end +class Dog < ActiveRecord::Base; end -end