Skip to content
Permalink
Browse files

Adjusting tests to deal with floating point madness

PostgreSQL 11 and 12 handle floating point values differently; the test
originally passed on PostgreSQL 12, but not on 11 (Travis). Now, with
floating point data truncated to only 6 digits, they run on both
versions of the DBMS.
See https://www.postgresql.org/docs/12/release-12.html
  • Loading branch information
espinafre authored and nyalldawson committed Jun 17, 2020
1 parent c521f39 commit 6a85309587d9eb9dd8d0c5832b8ad71f9f6aecec
Showing with 20 additions and 18 deletions.
  1. +17 −15 tests/src/python/test_provider_postgres.py
  2. +3 −3 tests/testdata/provider/testdata_pg_bigint_pk.sql
@@ -781,14 +781,15 @@ def testPktComposite(self):

fields = vl.fields()

f = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk3 = 3.1415927')))
# Only 6 decimals for PostgreSQL 11.
f = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk3 = 3.14159')))
# first of all: we must be able to fetch a valid feature
self.assertTrue(f.isValid())
self.assertEqual(f['pk1'], 1)
self.assertEqual(f['pk2'], 2)

# round() needed to make sure Python older than 3.8 do the right thing.
self.assertEqual(round(f['pk3'], 5), round(3.1415927, 5))
# Only 6 decimals for PostgreSQL 11.
self.assertEqual(f['pk3'], 3.14159)
self.assertEqual(f['value'], 'test 2')

# can we edit a field?
@@ -799,12 +800,12 @@ def testPktComposite(self):
# Did we get it right? Let's create a new QgsVectorLayer and try to read back our changes:
vl2 = QgsVectorLayer('{} sslmode=disable srid=4326 table="qgis_test"."tb_test_compound_pk" (geom) key=\'"pk1","pk2","pk3"\' '.format(self.dbconn), "test_compound2", "postgres")
self.assertTrue(vl2.isValid())
f2 = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk3 = 3.1415927')))
f2 = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk3 = 3.14159')))
self.assertTrue(f2.isValid())

# just making sure we have the correct feature
# round() needed to make sure Python older than 3.8 do the right thing.
self.assertEqual(round(f2['pk3'], 5), round(3.1415927, 5))
# Only 6 decimals for PostgreSQL 11.
self.assertEqual(f2['pk3'], 3.14159)

# Then, making sure we really did change our value.
self.assertEqual(f2['value'], 'Edited Test 2')
@@ -824,9 +825,7 @@ def testPktComposite(self):
f4 = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk2 = -9223372036854775800')))

self.assertTrue(f4.isValid())
# round() needed to make sure Python older than 3.8 do the right thing.
expected_attrs = [4, -9223372036854775800, round(7.29154, 5), 'other test']
gotten_attrs = [f4['pk1'], f4['pk2'], round(f4['pk3'], 5), f4['value']]
expected_attrs = [4, -9223372036854775800, 7.29154, 'other test']
self.assertEqual(f4.attributes(), expected_attrs)

# Finally, let's delete one of the features.
@@ -854,11 +853,13 @@ def testPktFloat(self):
vl = QgsVectorLayer('{} sslmode=disable srid=4326 key="pk" table="qgis_test"."tb_test_float_pk" (geom)'.format(self.dbconn), "test_floatpk", "postgres")
self.assertTrue(vl.isValid())
fields = vl.fields()
f = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 3.141592741')))
# floating point madness: PostgreSQL 11 only outputs 6 decimal digits for real type by default
# Thus, QGIS only stores 6 decimal digits in its attributes. For this reason,
# we must insert only 3.14159 instead of the more accurate 3.141592741 in the test table.
f = next(vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 3.14159')))
self.assertTrue(f.isValid())

# round() needed to make sure Python older than 3.8 do the right thing.
self.assertEqual(round(f['pk'], 5), round(3.1415927, 5))
self.assertEqual(f['pk'], 3.14159)
self.assertEqual(f['value'], 'first test')

# editing
@@ -869,7 +870,7 @@ def testPktFloat(self):
# checking out if we really wrote to the table
vl2 = QgsVectorLayer('{} sslmode=disable srid=4326 key="pk" table="qgis_test"."tb_test_float_pk" (geom)'.format(self.dbconn), "test_floatpk2", "postgres")
self.assertTrue(vl2.isValid())
f2 = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 3.141592741')))
f2 = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 3.14159')))

self.assertEqual(f2['value'], 'first check')

@@ -888,14 +889,15 @@ def testPktFloat(self):
self.assertEqual(f4['value'], 'newly inserted')

# Checking deletion
f5 = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 2.7182817')))
# same as above: no more than 6 digits of Euler's number in the testdata for PostgreSQL 11.
f5 = next(vl2.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 2.71828')))
self.assertTrue(f5.isValid())
vl2.startEditing()
vl2.deleteFeatures([f5.id()])
self.assertTrue(vl2.commitChanges())

# did we really delete?
f_iterator = vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 2.7182817'))
f_iterator = vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk = 2.71828'))
got_feature = True

try:
@@ -116,7 +116,7 @@ CREATE TABLE qgis_test.tb_test_compound_pk

INSERT INTO qgis_test.tb_test_compound_pk (pk1, pk2, pk3, value, geom) VALUES
(1, 1, 1.0, 'test 1', ST_SetSRID(ST_Point(-47.930, -15.818), 4326)),
(1, 2, 3.141592741, 'test 2', ST_SetSRID(ST_Point(-47.887, -15.864), 4326)),
(1, 2, 3.14159, 'test 2', ST_SetSRID(ST_Point(-47.887, -15.864), 4326)),
(2, 2, 2.718281828, 'test 3', ST_SetSRID(ST_Point(-47.902, -15.763), 4326)),
(2, 2, 1.0, 'test 4', ST_SetSRID(ST_Point(-47.952, -15.781), 4326));

@@ -128,5 +128,5 @@ CREATE TABLE qgis_test.tb_test_float_pk
);

INSERT INTO qgis_test.tb_test_float_pk (pk, value, geom) VALUES
(3.141592741, 'first test', ST_SetSRID(ST_Point(-47.887, -15.864), 4326)),
(2.718281828, 'second test', ST_SetSRID(ST_Point(-47.902, -15.763), 4326));
(3.14159, 'first test', ST_SetSRID(ST_Point(-47.887, -15.864), 4326)),
(2.71828, 'second test', ST_SetSRID(ST_Point(-47.902, -15.763), 4326));

0 comments on commit 6a85309

Please sign in to comment.
You can’t perform that action at this time.