spec/mri/pg_interface_spec.rb in pod4-0.7.2 vs spec/mri/pg_interface_spec.rb in pod4-0.8.0
- old
+ new
@@ -6,10 +6,13 @@
class TestPgInterface < PgInterface
set_table :customer
set_id_fld :id
+
+ # We open a lot of connections, unusually
+ def stop; close; end
end
class SchemaPgInterface < PgInterface
set_schema :public
set_table :customer
@@ -22,38 +25,53 @@
class BadPgInterface2 < PgInterface
set_id_fld :id
end
+class ProdPgInterface < PgInterface
+ set_table :product
+ set_id_fld :code
+end
+
describe TestPgInterface do
def db_setup(connect)
client = PG.connect(connect)
- client.exec(%Q|drop table if exists customer;|)
-
client.exec(%Q|
+ drop table if exists customer;
+ drop table if exists product;
+
create table customer (
- id serial,
+ id serial primary key,
name text,
level real null,
day date null,
timestamp timestamp null,
price money null,
- qty numeric null );| )
+ qty numeric null );
+ create table product (
+ code text,
+ name text );| )
+
ensure
client.finish if client
end
def fill_data(ifce)
@data.each{|r| ifce.create(r) }
end
+ def fill_product_data(ifce)
+ ifce.create( {code: "foo", name: "bar"} )
+ end
+
+
before(:all) do
@connect_hash = DB[:pg]
db_setup(@connect_hash)
@data = []
@@ -80,19 +98,31 @@
end
before do
- # TRUNCATE TABLE also resets the identity counter
- interface.execute(%Q|truncate table customer restart identity;|)
+ interface.execute(%Q|
+ truncate table customer restart identity;
+ truncate table product;|)
+
end
+ after do
+ # We open a lot of connections, unusually
+ interface.stop if interface
+ end
+
+
let(:interface) do
TestPgInterface.new(@connect_hash)
end
+ let(:prod_interface) do
+ ProdPgInterface.new(@connect_hash)
+ end
+
#####
it_behaves_like 'an interface' do
@@ -210,24 +240,33 @@
expect{ interface.read(id) }.not_to raise_exception
expect( interface.read(id).to_h ).to include ot.to_h
end
- it 'shouldnt have a problem with record values of nil' do
+ it 'shouldn\'t have a problem with record values of nil' do
record = {name: 'Ranger', price: nil}
expect{ interface.create(record) }.not_to raise_exception
id = interface.create(record)
expect( interface.read(id).to_h ).to include(record)
end
- it 'shouldnt have a problem with strings containing special characters' do
+ it 'shouldn\'t have a problem with strings containing special characters' do
record = {name: %Q|T'Challa""|, price: nil}
expect{ interface.create(record) }.not_to raise_exception
id = interface.create(record)
expect( interface.read(id).to_h ).to include(record)
end
+ it 'shouldn\'t have a problem with non-integer keys' do
+ hash = {code: "foo", name: "bar"}
+ id = prod_interface.create( Octothorpe.new(hash) )
+
+ expect( id ).to eq "foo"
+ expect{ prod_interface.read("foo") }.not_to raise_exception
+ expect( prod_interface.read("foo").to_h ).to include hash
+ end
+
end
##
describe '#read' do
@@ -282,10 +321,18 @@
expect( price ).to be_a_kind_of BigDecimal
expect( price ).to eq @data.first[:price]
end
+ it 'shouldn\'t have a problem with non-integer keys' do
+ # this is a 100% overlap with the create test above...
+ fill_product_data(prod_interface)
+
+ expect{ prod_interface.read("foo") }.not_to raise_exception
+ expect( prod_interface.read("foo").to_h ).to include(code: "foo", name: "bar")
+ end
+
end
##
describe '#list' do
@@ -335,12 +382,10 @@
it 'updates the record at ID with record parameter' do
record = {name: 'Booboo', price: 99.99}
interface.update(id, record)
- # It so happens that TinyTds returns money as BigDecimal --
- # this is a really good thing, even though it screws with our test.
expect( float_price( interface.read(id).to_h ) ).to include(record)
end
it 'raises a CantContinue if anything weird happens with the ID' do
expect{ interface.update(99, name: 'Booboo') }.
@@ -352,30 +397,36 @@
expect{ interface.update(id, smarts: 'more') }.
to raise_exception DatabaseError
end
- it 'shouldnt have a problem with record values of nil' do
+ it 'shouldn\'t have a problem with record values of nil' do
record = {name: 'Ranger', price: nil}
expect{ interface.update(id, record) }.not_to raise_exception
expect( interface.read(id).to_h ).to include(record)
end
- it 'shouldnt have a problem with strings containing special characters' do
+ it 'shouldn\'t have a problem with strings containing special characters' do
record = {name: %Q|T'Challa""|, price: nil}
expect{ interface.update(id, record) }.not_to raise_exception
expect( interface.read(id).to_h ).to include(record)
end
+ it 'shouldn\'t have a problem with non-integer keys' do
+ fill_product_data(prod_interface)
+ expect{ prod_interface.update("foo", name: "baz") }.not_to raise_error
+ expect( prod_interface.read("foo").to_h[:name] ).to eq "baz"
+ end
+
end
##
describe '#delete' do
- def list_contains(id)
- interface.list.find {|x| x[interface.id_fld] == id }
+ def list_contains(ifce, id)
+ ifce.list.find {|x| x[ifce.id_fld] == id }
end
let(:id) { interface.list.first[:id] }
before { fill_data(interface) }
@@ -384,15 +435,22 @@
expect{ interface.delete(:foo) }.to raise_exception CantContinue
expect{ interface.delete(99) }.to raise_exception CantContinue
end
it 'makes the record at ID go away' do
- expect( list_contains(id) ).to be_truthy
+ expect( list_contains(interface, id) ).to be_truthy
interface.delete(id)
- expect( list_contains(id) ).to be_falsy
+ expect( list_contains(interface, id) ).to be_falsy
end
+ it 'shouldn\'t have a problem with non-integer keys' do
+ fill_product_data(prod_interface)
+ expect( list_contains(prod_interface, "foo") ).to be_truthy
+ prod_interface.delete("foo")
+ expect( list_contains(prod_interface, "foo") ).to be_falsy
+ end
+
end
##
describe '#execute' do
@@ -421,10 +479,38 @@
end
##
+ describe '#executep' do
+
+ let(:sql) { 'delete from customer where cast(price as numeric) < %s and name = %s;' }
+
+ before { fill_data(interface) }
+
+ it 'requires an SQL string' do
+ expect{ interface.executep }.to raise_exception ArgumentError
+ expect{ interface.executep(nil) }.to raise_exception ArgumentError
+ expect{ interface.executep(14) }.to raise_exception ArgumentError
+ end
+
+ it 'raises some sort of Pod4 error if it runs into problems' do
+ expect{ interface.executep('delete from not_a_table where foo = %s', 12) }.
+ to raise_exception Pod4Error
+
+ end
+
+ it 'executes the string with the given parameters' do
+ expect{ interface.executep(sql, 12.0, 'Barney') }.not_to raise_exception
+ expect( interface.list.size ).to eq(@data.size - 1)
+ expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
+ end
+
+ end
+ ##
+
+
describe '#select' do
before { fill_data(interface) }
it 'requires an SQL string' do
@@ -455,9 +541,47 @@
expect( interface.list.size ).to eq(@data.size - 1)
expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
expect( ret ).to eq( [] )
end
+
+ end
+ ##
+
+
+ describe '#selectp' do
+
+ before { fill_data(interface) }
+
+ it 'requires an SQL string' do
+ expect{ interface.selectp }.to raise_exception ArgumentError
+ expect{ interface.selectp(nil) }.to raise_exception ArgumentError
+ expect{ interface.selectp(14) }.to raise_exception ArgumentError
+ end
+
+ it 'raises some sort of Pod4 error if it runs into problems' do
+ expect{ interface.selectp('select * from not_a_table where thingy = %s', 12) }.
+ to raise_exception Pod4Error
+
+ end
+
+ it 'returns the result of the sql' do
+ sql = 'select name from customer where cast(price as numeric) < %s;'
+
+ expect{ interface.selectp(sql, 2.0) }.not_to raise_exception
+ expect( interface.selectp(sql, 2.0) ).to eq( [{name: 'Barney'}] )
+ expect( interface.selectp(sql, 0.0) ).to eq( [] )
+ end
+
+ it 'works if you pass a non-select' do
+ sql = 'delete from customer where cast(price as numeric) < %s;'
+ ret = interface.selectp(sql, 2.0)
+
+ expect( interface.list.size ).to eq(@data.size - 1)
+ expect( interface.list.map{|r| r[:name] } ).not_to include 'Barney'
+ expect( ret ).to eq( [] )
+ end
+
end
##