Skip to content

Commit

Permalink
Boost test coverage for QgsRectangle
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 25, 2017
1 parent d704163 commit 20cc7a7
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/core/geometry/qgsrectangle.cpp
Expand Up @@ -254,7 +254,7 @@ QgsRectangle &QgsRectangle::operator+=( const QgsVector v )

bool QgsRectangle::isEmpty() const
{
return mXmax <= mXmin || mYmax <= mYmin;
return mXmax < mXmin || mYmax < mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
}

bool QgsRectangle::isNull() const
Expand Down
130 changes: 130 additions & 0 deletions tests/src/core/testqgsrectangle.cpp
Expand Up @@ -25,13 +25,37 @@ class TestQgsRectangle: public QObject
{
Q_OBJECT
private slots:
void isEmpty();
void manipulate();
void regression6194();
void operators();
void asVariant();
void referenced();
void minimal();
void grow();
void include();
void buffered();
void isFinite();
void dataStream();
};

void TestQgsRectangle::isEmpty()
{
QVERIFY( QgsRectangle().isEmpty() );
QVERIFY( QgsRectangle( 1, 2, 1, 4 ).isEmpty() );
QVERIFY( QgsRectangle( 2, 1, 4, 1 ).isEmpty() );
//constructor should normalize
QVERIFY( !QgsRectangle( 2, 2, 1, 4 ).isEmpty() );
QVERIFY( !QgsRectangle( 1, 2, 2, 1 ).isEmpty() );

QgsRectangle r( 2, 2, 3, 4 );
r.setXMaximum( 1 );
QVERIFY( r.isEmpty() );
r = QgsRectangle( 2, 2, 3, 4 );
r.setYMaximum( 1 );
QVERIFY( r.isEmpty() );
}

void TestQgsRectangle::manipulate()
{
// Set up two intersecting rectangles and normalize
Expand Down Expand Up @@ -155,5 +179,111 @@ void TestQgsRectangle::referenced()
QCOMPARE( rect2.crs().authid(), QStringLiteral( "EPSG:28356" ) );
}

void TestQgsRectangle::minimal()
{
QgsRectangle rect1 = QgsRectangle( 10.0, 20.0, 110.0, 220.0 );
rect1.setMinimal();
QVERIFY( rect1.isEmpty() );
QVERIFY( rect1.isNull() );
}

void TestQgsRectangle::grow()
{
QgsRectangle rect1 = QgsRectangle( 10.0, 20.0, 110.0, 220.0 );
rect1.grow( 11 );
QCOMPARE( rect1.xMinimum(), -1.0 );
QCOMPARE( rect1.yMinimum(), 9.0 );
QCOMPARE( rect1.xMaximum(), 121.0 );
QCOMPARE( rect1.yMaximum(), 231.0 );

QgsRectangle rect2 = QgsRectangle( -110.0, -220.0, -10.0, -20.0 );
rect2.grow( 11 );
QCOMPARE( rect2.xMinimum(), -121.0 );
QCOMPARE( rect2.yMinimum(), -231.0 );
QCOMPARE( rect2.xMaximum(), 1.0 );
QCOMPARE( rect2.yMaximum(), -9.0 );
}

void TestQgsRectangle::include()
{
QgsRectangle rect1 = QgsRectangle( 10.0, 20.0, 110.0, 220.0 );
// inside
rect1.include( QgsPointXY( 15, 50 ) );
QCOMPARE( rect1.xMinimum(), 10.0 );
QCOMPARE( rect1.yMinimum(), 20.0 );
QCOMPARE( rect1.xMaximum(), 110.0 );
QCOMPARE( rect1.yMaximum(), 220.0 );

rect1.include( QgsPointXY( 5, 50 ) );
QCOMPARE( rect1.xMinimum(), 5.0 );
QCOMPARE( rect1.yMinimum(), 20.0 );
QCOMPARE( rect1.xMaximum(), 110.0 );
QCOMPARE( rect1.yMaximum(), 220.0 );

rect1.include( QgsPointXY( 15, 12 ) );
QCOMPARE( rect1.xMinimum(), 5.0 );
QCOMPARE( rect1.yMinimum(), 12.0 );
QCOMPARE( rect1.xMaximum(), 110.0 );
QCOMPARE( rect1.yMaximum(), 220.0 );

rect1.include( QgsPointXY( 115, 12 ) );
QCOMPARE( rect1.xMinimum(), 5.0 );
QCOMPARE( rect1.yMinimum(), 12.0 );
QCOMPARE( rect1.xMaximum(), 115.0 );
QCOMPARE( rect1.yMaximum(), 220.0 );

rect1.include( QgsPointXY( 115, 242 ) );
QCOMPARE( rect1.xMinimum(), 5.0 );
QCOMPARE( rect1.yMinimum(), 12.0 );
QCOMPARE( rect1.xMaximum(), 115.0 );
QCOMPARE( rect1.yMaximum(), 242.0 );

}

void TestQgsRectangle::buffered()
{
QgsRectangle rect = QgsRectangle( 10.0, 20.0, 110.0, 220.0 );
QgsRectangle rect1 = rect.buffered( 11 );
QCOMPARE( rect1.xMinimum(), -1.0 );
QCOMPARE( rect1.yMinimum(), 9.0 );
QCOMPARE( rect1.xMaximum(), 121.0 );
QCOMPARE( rect1.yMaximum(), 231.0 );

rect = QgsRectangle( -110.0, -220.0, -10.0, -20.0 );
QgsRectangle rect2 = rect.buffered( 11 );
QCOMPARE( rect2.xMinimum(), -121.0 );
QCOMPARE( rect2.yMinimum(), -231.0 );
QCOMPARE( rect2.xMaximum(), 1.0 );
QCOMPARE( rect2.yMaximum(), -9.0 );
}

void TestQgsRectangle::isFinite()
{
QVERIFY( QgsRectangle( 1, 2, 3, 4 ).isFinite() );
QVERIFY( !QgsRectangle( std::numeric_limits<double>::infinity(), 2, 3, 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, std::numeric_limits<double>::infinity(), 3, 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, 2, std::numeric_limits<double>::infinity(), 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, 2, 3, std::numeric_limits<double>::infinity() ).isFinite() );
QVERIFY( !QgsRectangle( std::numeric_limits<double>::quiet_NaN(), 2, 3, 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, std::numeric_limits<double>::quiet_NaN(), 3, 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, 2, std::numeric_limits<double>::quiet_NaN(), 4 ).isFinite() );
QVERIFY( !QgsRectangle( 1, 2, 3, std::numeric_limits<double>::quiet_NaN() ).isFinite() );
}

void TestQgsRectangle::dataStream()
{
QgsRectangle original( 10.1, 20.2, 110.3, 220.4 );

QByteArray ba;
QDataStream ds( &ba, QIODevice::ReadWrite );
ds << original;

QgsRectangle result;
ds.device()->seek( 0 );
ds >> result;

QCOMPARE( result, original );
}

QGSTEST_MAIN( TestQgsRectangle )
#include "testqgsrectangle.moc"
31 changes: 22 additions & 9 deletions tests/src/python/test_qgsrectangle.py
Expand Up @@ -24,17 +24,8 @@

class TestQgsRectangle(unittest.TestCase):

# Because isEmpty() is not returning expected result in 9b0fee3

@unittest.expectedFailure
def testCtor(self):
rect = QgsRectangle(5.0, 5.0, 10.0, 10.0)

myExpectedResult = True
myResult = rect.isEmpty()
myMessage = ('Expected: %s Got: %s' % (myExpectedResult, myResult))
assert rect.isEmpty(), myMessage

myMessage = ('Expected: %s\nGot: %s\n' %
(5.0, rect.xMinimum()))
assert rect.xMinimum() == 5.0, myMessage
Expand Down Expand Up @@ -204,13 +195,22 @@ def testAsWktPolygon(self):

def testToString(self):
"""Test the different string representations"""
self.assertEqual(QgsRectangle().toString(), 'Empty')
rect = QgsRectangle(0, 0.1, 0.2, 0.3)
myExpectedString = '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000'
myString = rect.toString()
myMessage = ('Expected: %s\nGot: %s\n' %
(myExpectedString, myString))
assert myString == myExpectedString, myMessage

# can't test the actual result here, because floating point inaccuracies mean the result is unpredictable
# at this precision
self.assertEqual(len(rect.toString(20)), 93)

myMessage = ('Expected: %s\nGot: %s\n' %
(myExpectedString, myString))
assert myString == myExpectedString, myMessage

myExpectedString = '0,0 : 0,0'
myString = rect.toString(0)
myMessage = ('Expected: %s\nGot: %s\n' %
Expand Down Expand Up @@ -242,6 +242,11 @@ def testToString(self):
(myExpectedString, myString))
assert myString == myExpectedString, myMessage

def testAsPolygon(self):
"""Test string representation as polygon"""
self.assertEqual(QgsRectangle().asPolygon(), '0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000')
self.assertEqual(QgsRectangle(0, 0.1, 0.2, 0.3).asPolygon(), '0.00000000 0.10000000, 0.00000000 0.30000000, 0.20000000 0.30000000, 0.20000000 0.10000000, 0.00000000 0.10000000')

def testToBox3d(self):
rect = QgsRectangle(0, 0.1, 0.2, 0.3)
box = rect.toBox3d(0.4, 0.5)
Expand All @@ -261,6 +266,14 @@ def testOperators(self):
rect1 -= rect1.center() - QgsPointXY(0, 0)
assert rect1.center() == QgsPointXY(0, 0)

def testInvert(self):
rect = QgsRectangle(0, 0.1, 0.2, 0.3)
rect.invert()
self.assertEqual(rect.xMinimum(), 0.1)
self.assertEqual(rect.yMinimum(), 0)
self.assertEqual(rect.xMaximum(), 0.3)
self.assertEqual(rect.yMaximum(), 0.2)


if __name__ == '__main__':
unittest.main()

0 comments on commit 20cc7a7

Please sign in to comment.