Skip to content

Commit

Permalink
Introduce custom Rspec matcher comparing derived and expected SQL
Browse files Browse the repository at this point in the history
  • Loading branch information
nikola committed Jan 23, 2017
1 parent 5ab4ccc commit 91f348b
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 81 deletions.
30 changes: 18 additions & 12 deletions spec/aggregate_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,29 @@

describe Dumbo::Aggregate do
let(:avg) do
oid = Dumbo::DB.exec("SELECT p.oid
FROM pg_proc p
JOIN pg_aggregate ag ON p.oid = ag.aggfnoid
WHERE proname='avg' AND pg_get_function_arguments(p.oid) = 'integer'").first['oid']
Dumbo::Aggregate.new(oid)
sql = <<-SQL
SELECT p.oid
FROM pg_proc p
JOIN pg_aggregate ag ON p.oid = ag.aggfnoid
WHERE proname='avg' AND pg_get_function_arguments(p.oid) = 'integer'
SQL

Dumbo::Aggregate.new(Dumbo::DB.exec(sql).first['oid'])
end

let(:min) do
oid = Dumbo::DB.exec("SELECT p.oid
FROM pg_proc p
JOIN pg_aggregate ag ON p.oid = ag.aggfnoid
WHERE proname='min' AND pg_get_function_arguments(p.oid) = 'integer'").first['oid']
Dumbo::Aggregate.new(oid)
sql = <<-SQL
SELECT p.oid
FROM pg_proc p
JOIN pg_aggregate ag ON p.oid = ag.aggfnoid
WHERE proname='min' AND pg_get_function_arguments(p.oid) = 'integer'
SQL

Dumbo::Aggregate.new(Dumbo::DB.exec(sql).first['oid'])
end

it 'avg should have a sql representation' do
expect(avg.to_sql).to eq <<-SQL.gsub(/^ {6}/, '')
expect(avg.to_sql).to eq_sql <<-SQL
CREATE AGGREGATE avg(integer) (
SFUNC = int4_avg_accum,
STYPE = int8[],
Expand All @@ -29,7 +35,7 @@
end

it 'min should have a sql representation' do
expect(min.to_sql).to eq <<-SQL.gsub(/^ {6}/, '')
expect(min.to_sql).to eq_sql <<-SQL
CREATE AGGREGATE min(integer) (
SFUNC = int4smaller,
STYPE = int4,
Expand Down
24 changes: 14 additions & 10 deletions spec/cast_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
require 'spec_helper'

describe Dumbo::Cast do
let(:cast) do
oid = Dumbo::DB.exec("SELECT ca.oid
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
WHERE format_type(st.oid,NULL) = 'bigint'
AND format_type(tt.oid,tt.typtypmod) = 'integer';").first['oid']
Dumbo::Cast.new(oid)
sql = <<-SQL
SELECT ca.oid
FROM pg_cast ca
JOIN pg_type st ON st.oid=castsource
JOIN pg_type tt ON tt.oid=casttarget
WHERE format_type(st.oid,NULL) = 'bigint'
AND format_type(tt.oid,tt.typtypmod) = 'integer'
SQL

Dumbo::Cast.new(Dumbo::DB.exec(sql).first['oid'])
end

it 'should have a sql representation' do
expect(cast.to_sql).to eq <<-SQL.gsub(/^ {6}/, '')
expect(cast.to_sql).to eq_sql <<-SQL
CREATE CAST (bigint AS integer)
WITH FUNCTION int4(bigint)
AS ASSIGNMENT;
SQL
end
SQL
end
end
42 changes: 20 additions & 22 deletions spec/extension_migrator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,30 @@
let(:migrator) { Dumbo::ExtensionMigrator.new('dumbo_sample', '0.0.1', '0.0.2') }

it 'should provide upgrade sql' do
expect(migrator.upgrade).to eq <<-SQL.gsub(/^ {4}/, '').strip
----functions----
CREATE OR REPLACE FUNCTION foo(integer)
RETURNS integer
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $function$
BEGIN
RETURN $1 + 10;
END
$function$;
expect(migrator.upgrade).to eq_sql <<-SQL
----functions----
CREATE OR REPLACE FUNCTION foo(integer)
RETURNS integer
LANGUAGE plpgsql IMMUTABLE STRICT
AS $function$
BEGIN
RETURN $1 + 10;
END
$function$;
SQL
end

it 'should provide downgrade sql' do
expect(migrator.downgrade).to eq <<-SQL.gsub(/^ {4}/, '').strip
----functions----
CREATE OR REPLACE FUNCTION foo(integer)
RETURNS integer
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $function$
BEGIN
RETURN $1;
END
$function$;
expect(migrator.downgrade).to eq_sql <<-SQL
----functions----
CREATE OR REPLACE FUNCTION foo(integer)
RETURNS integer
LANGUAGE plpgsql IMMUTABLE STRICT
AS $function$
BEGIN
RETURN $1;
END
$function$;
SQL
end
end
10 changes: 4 additions & 6 deletions spec/operator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@

describe Dumbo::Operator do
let(:operator) do
res = Dumbo::DB.exec <<-SQL
sql = <<-SQL
SELECT oid FROM pg_operator
WHERE oprname = '&&'
AND format_type(oprleft, NULL) = 'box'
AND format_type(oprright, NULL) = 'box'
SQL

oid = res.first['oid']

Dumbo::Operator.new(oid).get
Dumbo::Operator.new(Dumbo::DB.exec(sql).first['oid']).get
end

it 'should have a sql representation' do
expect(operator.to_sql).to eq <<-SQL.gsub(/^ {6}/, '')
expect(operator.to_sql).to eq_sql <<-SQL
CREATE OPERATOR && (
PROCEDURE = box_overlap,
LEFTARG = box,
Expand All @@ -24,7 +22,7 @@
RESTRICT = areasel,
JOIN = areajoinsel
);
SQL
SQL
end

it 'should have a uniq identfier' do
Expand Down
10 changes: 9 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@
end
end

require 'dumbo/test/regression_helper' if ENV['DUMBO_REGRESSION']
def squish(str)
str.gsub(/\A[[:space:]]+/, '').gsub(/[[:space:]]+\z/, '').gsub(/[[:space:]]+/, ' ')
end

RSpec::Matchers.define :eq_sql do |expected|
match do |actual|
squish(actual) == squish(expected)
end
end
60 changes: 30 additions & 30 deletions spec/type_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@
let(:type) { extension.types.select { |t| t.name == type_name }.first }

it 'should have a sql representation' do
expect(type.to_sql).to eq <<-SQL.gsub(/^ {4}/, '')
CREATE TYPE elephant_base(
INPUT=elephant_in,
OUTPUT=elephant_out,
RECEIVE=-,
SEND=-,
ANALYZE=-,
CATEGORY='U',
DEFAULT='',
INTERNALLENGTH=-1,
ALIGNMENT=int,
STORAGE=PLAIN
);
expect(type.to_sql).to eq_sql <<-SQL
CREATE TYPE elephant_base(
INPUT=elephant_in,
OUTPUT=elephant_out,
RECEIVE=-,
SEND=-,
ANALYZE=-,
CATEGORY='U',
DEFAULT='',
INTERNALLENGTH=-1,
ALIGNMENT=int,
STORAGE=PLAIN
);
SQL
end

Expand All @@ -54,11 +54,11 @@
let(:type_name) { 'elephant_composite' }

it 'should have a sql representation' do
expect(type.to_sql).to eq <<-SQL.gsub(/^ {4}/, '')
CREATE TYPE elephant_composite AS (
weight integer,
name text
);
expect(type.to_sql).to eq_sql <<-SQL
CREATE TYPE elephant_composite AS (
weight integer,
name text
);
SQL
end

Expand All @@ -69,12 +69,12 @@
let(:type_name) { 'elephant_range' }

it 'should have a sql representation' do
expect(type.to_sql).to eq <<-SQL.gsub(/^ {4}/, '')
CREATE TYPE elephant_range AS RANGE (
SUBTYPE=float8,
SUBTYPE_OPCLASS=float8_ops,
SUBTYPE_DIFF=float8mi
);
expect(type.to_sql).to eq_sql <<-SQL
CREATE TYPE elephant_range AS RANGE (
SUBTYPE=float8,
SUBTYPE_OPCLASS=float8_ops,
SUBTYPE_DIFF=float8mi
);
SQL
end

Expand All @@ -85,12 +85,12 @@
let(:type_name) { 'elephant_enum' }

it 'should have a sql representation' do
expect(type.to_sql).to eq <<-SQL.gsub(/^ {4}/, '')
CREATE TYPE elephant_enum AS ENUM (
'infant',
'child',
'adult'
);
expect(type.to_sql).to eq_sql <<-SQL
CREATE TYPE elephant_enum AS ENUM (
'infant',
'child',
'adult'
);
SQL
end

Expand Down

0 comments on commit 91f348b

Please sign in to comment.