QGIS/tests/src/core/testziplayer.cpp
Nyall Dawson 8c3939e756 More efficient use of QStrings
- use .isEmpty() instead of == QLatin1String( "" ) to check for
empty strings
- use .clear() instead of = QLatin1String( "" ) to empty a string
- remove unnecessary QString initializations
2017-09-28 05:25:51 +10:00

527 lines
17 KiB
C++

/***************************************************************************
testziplayer.cpp
--------------------------------------
Date : Sun Sep 16 12:22:23 AKDT 2007
Copyright : (C) 2012 Etienne Tourigny and Tim Sutton
Email : etourigny.dev@gmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgstest.h"
#include <QObject>
#include <QString>
#include <QApplication>
#include <QFileInfo>
//qgis includes...
#include "qgsapplication.h"
#include "qgsproviderregistry.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsdataitem.h"
#include "qgsconfig.h"
#include "qgsrasterrenderer.h"
#include "qgssettings.h"
#include <gdal.h>
/** \ingroup UnitTests
* This is a unit test to verify that zip vector layers work
*/
class TestZipLayer: public QObject
{
Q_OBJECT
private:
QString mDataDir;
QString mScanZipSetting;
QStringList mScanZipSettings;
QString mSettingsKey;
// get map layer using Passthru
QgsMapLayer *getLayer( const QString &myPath, const QString &myName, const QString &myProviderKey );
bool testZipItemPassthru( const QString &myFileName, const QString &myProviderKey );
// get map layer using QgsZipItem (only 1 child)
QgsMapLayer *getZipLayer( const QString &myPath, const QString &myName );
// test item(s) in zip item (supply name or test all)
bool testZipItem( const QString &myFileName, const QString &myChildName = QString(), const QString &myDriverName = QString() );
// get layer transparency to test for .qml loading
int getLayerTransparency( const QString &myFileName, const QString &myProviderKey, const QString &myScanZipSetting = QStringLiteral( "basic" ) );
bool testZipItemTransparency( const QString &myFileName, const QString &myProviderKey, int myTarget );
private slots:
// init / cleanup
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init() {} // will be called before each testfunction is executed.
void cleanup() {} // will be called after every testfunction.
// tests
// test for .zip and .gz files using all options
void testPassthruVectorZip();
void testPassthruVectorTar();
void testPassthruVectorGzip();
void testPassthruRasterZip();
void testPassthruRasterTar();
void testPassthruRasterGzip();
// test both "Basic Scan" and "Full scan" for .zip files
void testZipItemRaster();
void testTarItemRaster();
void testZipItemVector();
void testTarItemVector();
void testZipItemAll();
void testTarItemAll();
// test that styles are loaded from .qml files outside zip files
#if 0
// TODO - find a simple way to test vector style loading
void testZipItemVectorTransparency();
void testTarItemVectorTransparency();
void testGzipItemVectorTransparency();
#endif
void testZipItemRasterTransparency();
void testTarItemRasterTransparency();
void testGzipItemRasterTransparency();
//make sure items inside subfolders can be read
void testZipItemSubfolder();
void testTarItemSubfolder();
//make sure .vrt items are loaded by proper provider (gdal/ogr)
void testZipItemVRT();
};
QgsMapLayer *TestZipLayer::getLayer( const QString &myPath, const QString &myName, const QString &myProviderKey )
{
QString fullName = myName;
if ( fullName.isEmpty() )
{
QFileInfo myFileInfo( myPath );
fullName = myFileInfo.completeBaseName();
}
QgsMapLayer *myLayer = nullptr;
if ( myProviderKey == QLatin1String( "ogr" ) )
{
myLayer = new QgsVectorLayer( myPath, fullName, QStringLiteral( "ogr" ) );
}
else if ( myProviderKey == QLatin1String( "gdal" ) )
{
myLayer = new QgsRasterLayer( myPath, fullName, QStringLiteral( "gdal" ) );
}
// item should not have other provider key, but if it does will return nullptr
return myLayer;
}
QgsMapLayer *TestZipLayer::getZipLayer( const QString &myPath, const QString &myName )
{
QgsMapLayer *myLayer = nullptr;
QgsDirectoryItem *dirItem = new QgsDirectoryItem( nullptr, QStringLiteral( "/" ), QLatin1String( "" ) );
QgsDataItem *myItem = QgsZipItem::itemFromPath( dirItem, myPath, myName );
if ( myItem )
{
QgsLayerItem *layerItem = dynamic_cast<QgsLayerItem *>( myItem );
if ( layerItem )
myLayer = getLayer( layerItem->path(), layerItem->name(), layerItem->providerKey() );
}
delete myItem;
delete dirItem;
return myLayer;
}
bool TestZipLayer::testZipItemPassthru( const QString &myFileName, const QString &myProviderKey )
{
QgsMapLayer *myLayer = getLayer( myFileName, QLatin1String( "" ), myProviderKey );
bool ok = myLayer && myLayer->isValid();
if ( myLayer )
delete myLayer;
return ok;
}
bool TestZipLayer::testZipItem( const QString &myFileName, const QString &myChildName, const QString &myProviderName )
{
QgsDebugMsg( QString( "\n=======================================\nfile = %1 name = %2 provider = %3"
).arg( myFileName, myChildName, myProviderName ) );
QFileInfo myFileInfo( myFileName );
QgsZipItem *myZipItem = new QgsZipItem( nullptr, myFileInfo.fileName(), myFileName );
myZipItem->populate();
// wait until populated in separate thread
QTime time;
time.start();
while ( myZipItem->state() != QgsDataItem::Populated && time.elapsed() < 5000 )
{
QTest::qSleep( 100 );
QCoreApplication::processEvents();
}
QgsDebugMsg( QString( "time.elapsed() = %1 ms" ).arg( time.elapsed() ) );
bool ok = false;
QVector<QgsDataItem *> myChildren = myZipItem->children();
QgsDebugMsg( QString( "has %1 items" ).arg( myChildren.size() ) );
if ( !myChildren.isEmpty() )
{
Q_FOREACH ( QgsDataItem *item, myChildren )
{
QgsDebugMsg( QString( "child name=%1" ).arg( item->name() ) );
QgsLayerItem *layerItem = dynamic_cast<QgsLayerItem *>( item );
if ( layerItem )
{
QgsDebugMsg( QString( "child name=%1 provider=%2 path=%3" ).arg( layerItem->name(), layerItem->providerKey(), layerItem->path() ) );
if ( myChildName.isEmpty() || myChildName == item->name() )
{
QgsMapLayer *layer = getLayer( layerItem->path(), layerItem->name(), layerItem->providerKey() );
if ( layer )
{
// we got a layer, check if it is valid and exit
// if no child name given in argument, then pass to next one (unless current child is invalid)
QgsDebugMsg( QString( "valid: %1" ).arg( layer->isValid() ) );
ok = layer->isValid();
delete layer;
if ( ! ok )
{
QWARN( QString( "Invalid layer %1" ).arg( layerItem->path() ).toLocal8Bit().data() );
}
if ( myChildName.isEmpty() )
{
if ( ! ok )
break;
}
else
{
//verify correct provider was used
if ( !myProviderName.isEmpty() )
{
ok = ( myProviderName == layerItem->providerKey() );
if ( ! ok )
{
QWARN( QString( "Layer %1 opened by provider %2, expecting %3"
).arg( layerItem->path(), layerItem->providerKey(), myProviderName ).toLocal8Bit().data() );
}
}
break;
}
}
else
{
QWARN( QString( "Invalid layer %1" ).arg( layerItem->path() ).toLocal8Bit().data() );
break;
}
}
}
else
{
QWARN( QString( "Invalid layer %1" ).arg( layerItem ? layerItem->path() : "(null)" ).toLocal8Bit().data() );
break;
}
}
}
delete myZipItem;
return ok;
}
int TestZipLayer::getLayerTransparency( const QString &myFileName, const QString &myProviderKey, const QString &myScanZipSetting )
{
int myTransparency = -1;
QgsSettings settings;
settings.setValue( mSettingsKey, myScanZipSetting );
if ( myScanZipSetting != settings.value( mSettingsKey ).toString() )
return myTransparency;
QgsMapLayer *myLayer = nullptr;
if ( myFileName.endsWith( QLatin1String( ".gz" ), Qt::CaseInsensitive ) )
myLayer = getLayer( myFileName, QLatin1String( "" ), myProviderKey );
else
myLayer = getZipLayer( myFileName, QLatin1String( "" ) );
if ( myLayer && myLayer->isValid() )
{
// myTransparency = myLayer->getTransparency();
if ( myLayer->type() == QgsMapLayer::RasterLayer )
{
QgsRasterLayer *layer = dynamic_cast<QgsRasterLayer *>( myLayer );
if ( layer && layer->renderer() )
{
myTransparency = std::ceil( layer->renderer()->opacity() * 255 );
}
}
}
else
QWARN( QString( "Could not open filename %1 using %2 provider" ).arg( myFileName, myProviderKey ).toLocal8Bit().data() );
if ( myLayer )
delete myLayer;
return myTransparency;
}
bool TestZipLayer::testZipItemTransparency( const QString &myFileName, const QString &myProviderKey, int myTarget )
{
int myTransparency;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
myTransparency = getLayerTransparency( myFileName, myProviderKey, s );
if ( myTransparency != myTarget )
{
QWARN( QString( "Transparency of %1 is %2, should be %3" ).arg( myFileName ).arg( myTransparency ).arg( myTarget ).toLocal8Bit().data() );
return false;
}
}
return true;
}
// slots
void TestZipLayer::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
// output test environment
QgsApplication::showSettings();
qDebug() << "GDAL version (build): " << GDAL_RELEASE_NAME;
qDebug() << "GDAL version (runtime): " << GDALVersionInfo( "RELEASE_NAME" );
// save data dir
QFile::remove( QDir::tempPath() + "/testzip.zip" );
QVERIFY( QFile::copy( QString( TEST_DATA_DIR ) + "/zip/" + "testzip.zip", QDir::tempPath() + "/testzip.zip" ) );
mDataDir = QStringLiteral( TEST_DATA_DIR ) + "/zip/";
// Set up the QgsSettings environment
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );
// save current zipSetting value
QgsSettings settings;
mSettingsKey = QStringLiteral( "/qgis/scanZipInBrowser2" );
mScanZipSetting = settings.value( mSettingsKey, "" ).toString();
mScanZipSettings << QLatin1String( "" ) << QStringLiteral( "basic" ) << QStringLiteral( "full" );
}
void TestZipLayer::cleanupTestCase()
{
QgsApplication::exitQgis();
// restore zipSetting
QgsSettings settings;
settings.setValue( mSettingsKey, mScanZipSetting );
}
void TestZipLayer::testPassthruVectorZip()
{
QgsSettings settings;
QString myFileName = mDataDir + "points2.zip";
QgsDebugMsg( "GDAL: " + QString( GDAL_RELEASE_NAME ) );
QgsDebugMsg( "FILE: " + QString( myFileName ) );
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( myFileName, "ogr" ) );
}
}
void TestZipLayer::testPassthruVectorTar()
{
QgsSettings settings;
QString myFileName = mDataDir + "points2.tar";
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( myFileName, "ogr" ) );
}
}
void TestZipLayer::testPassthruVectorGzip()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( mDataDir + "points3.geojson.gz", "ogr" ) );
}
}
void TestZipLayer::testPassthruRasterZip()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( mDataDir + "landsat_b1.zip", "gdal" ) );
}
}
void TestZipLayer::testPassthruRasterTar()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( mDataDir + "landsat_b1.tar", "gdal" ) );
}
}
void TestZipLayer::testPassthruRasterGzip()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItemPassthru( mDataDir + "landsat_b1.tif.gz", "gdal" ) );
}
}
void TestZipLayer::testZipItemRaster()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "landsat_b1.tif" ) );
}
}
void TestZipLayer::testTarItemRaster()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( mDataDir + "testtar.tgz", "landsat_b1.tif" ) );
}
}
void TestZipLayer::testZipItemVector()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "points.shp" ) );
}
}
void TestZipLayer::testTarItemVector()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( mDataDir + "testtar.tgz", "points.shp" ) );
}
}
void TestZipLayer::testZipItemAll()
{
// test for all items inside zip, using zipSetting 3 (Full Scan) which will ignore invalid items
// using zipSetting 2 (Basic Scan) would raise errors, because QgsZipItem would not test for valid items
// and return child names of the invalid items
// test file does not contain invalid items (some of dash tests failed because of them)
QgsSettings settings;
settings.setValue( mSettingsKey, "full" );
QVERIFY( "full" == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "" ) );
}
void TestZipLayer::testTarItemAll()
{
QgsSettings settings;
settings.setValue( mSettingsKey, "full" );
QVERIFY( "full" == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( mDataDir + "testtar.tgz", "" ) );
}
#if 0
void TestZipLayer::testZipItemVectorTransparency()
{
#if GDAL_VERSION_NUM < 1800
QSKIP( "This test requires GDAL >= 1.8", SkipSingle );
#endif
QVERIFY( testZipItemTransparency( mDataDir + "points2.zip", "ogr", 250 ) );
}
void TestZipLayer::testTarItemVectorTransparency()
{
#if GDAL_VERSION_NUM < 1800
QSKIP( "This test requires GDAL >= 1.8", SkipSingle );
#endif
QVERIFY( testZipItemTransparency( mDataDir + "points2.tar", "ogr", 250 ) );
}
void TestZipLayer::testGzipItemVectorTransparency()
{
#if GDAL_VERSION_NUM < 1700
QSKIP( "This test requires GDAL >= 1.7", SkipSingle );
#endif
QVERIFY( testZipItemTransparency( mDataDir + "points3.geojson.gz", "ogr", 250 ) );
}
#endif
void TestZipLayer::testZipItemRasterTransparency()
{
QVERIFY( testZipItemTransparency( mDataDir + "landsat_b1.zip", "gdal", 250 ) );
}
void TestZipLayer::testTarItemRasterTransparency()
{
QVERIFY( testZipItemTransparency( mDataDir + "landsat_b1.tar", "gdal", 250 ) );
}
void TestZipLayer::testGzipItemRasterTransparency()
{
QVERIFY( testZipItemTransparency( mDataDir + "landsat_b1.tif.gz", "gdal", 250 ) );
}
void TestZipLayer::testZipItemSubfolder()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "folder/folder2/landsat_b2.tif" ) );
}
}
void TestZipLayer::testTarItemSubfolder()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( mDataDir + "testtar.tgz", "folder/folder2/landsat_b2.tif" ) );
}
}
void TestZipLayer::testZipItemVRT()
{
QgsSettings settings;
Q_FOREACH ( const QString &s, mScanZipSettings )
{
settings.setValue( mSettingsKey, s );
QVERIFY( s == settings.value( mSettingsKey ).toString() );
QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "landsat_b1.vrt", "gdal" ) );
// this file is buggy with gdal svn - skip for now
// QVERIFY( testZipItem( QDir::tempPath() + "/testzip.zip", "points.vrt", "ogr" ) );
}
}
QGSTEST_MAIN( TestZipLayer )
#include "testziplayer.moc"