Skip to content

Commit

Permalink
[tests] Add test for unloading Expression Functions from projects (on…
Browse files Browse the repository at this point in the history
… project close) and reloading user ones, specifically to restore overwritten user functions when opening a project with expressions inside
  • Loading branch information
gacarrillor committed Sep 6, 2024
1 parent 52e581a commit fb0cafd
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ tests/testdata/raster/band3_float32_noct_epsg4326.tif.aux.xml
tests/testdata/raster/band3_int16_noct_epsg4326.tif.aux.xml
tests/testdata/tenbytenraster.asc.aux.xml
tests/testdata/test_plugin_path/plugin_started.txt
tests/testdata/test_qgis_config_path/profiles/default/*
!tests/testdata/test_qgis_config_path/profiles/default/python
tests/testdata/widget_config.qlr
tests/testdata/zip/testtar.tgz.properties
venv
1 change: 1 addition & 0 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -2759,6 +2759,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

friend class TestQgisAppPython;
friend class TestQgisApp;
friend class TestQgsProjectExpressions;
friend class QgisAppInterface;
friend class QgsAppScreenShots;
};
Expand Down
1 change: 1 addition & 0 deletions tests/src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ endif()

if (WITH_BINDINGS)
set(TESTS ${TESTS} testqgisapppython.cpp)
set(TESTS ${TESTS} testqgsprojectexpressions.cpp)
endif()

foreach(TESTSRC ${TESTS})
Expand Down
109 changes: 109 additions & 0 deletions tests/src/app/testqgsprojectexpressions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/***************************************************************************
testqgsprojectexpressions.cpp
--------------------
Date : Aug 2024
Copyright : (C) 2024 by Germán Carrillo
Email : german at opengis dot ch
***************************************************************************
* *
* 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 <QApplication>
#include <QObject>
#include <QSplashScreen>
#include <QString>
#include <QStringList>
#include "qgstest.h"

#include <qgisapp.h>
#include <qgsapplication.h>

/**
* \ingroup UnitTests
* This is a unit test for the Save Python Expression in project support.
*/
class TestQgsProjectExpressions : public QObject
{
Q_OBJECT

public:
TestQgsProjectExpressions();

private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.

void projectExpressions();

private:
QgisApp *mQgisApp = nullptr;
};

TestQgsProjectExpressions::TestQgsProjectExpressions() = default;

//runs before all tests
void TestQgsProjectExpressions::initTestCase()
{
const QByteArray configPath = QByteArray( TEST_DATA_DIR ) + "/test_qgis_config_path";
qputenv( "QGIS_CUSTOM_CONFIG_PATH", configPath );

// Set up the QgsSettings environment
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );

qDebug() << "TestQgsProjectExpressions::initTestCase()";
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();
mQgisApp = new QgisApp();
mQgisApp->loadPythonSupport();
}

//runs after all tests
void TestQgsProjectExpressions::cleanupTestCase()
{
QgsApplication::exitQgis();
}

void TestQgsProjectExpressions::projectExpressions()
{
const int count_before_project = QgsExpression::functionCount();
QVERIFY( QgsExpression::functionIndex( QStringLiteral( "mychoice" ) ) != -1 ); // User expression loaded

const QString myExpression = QStringLiteral( "mychoice(1, 2)" );
QgsExpression exp( QStringLiteral( "mychoice(1, 2)" ) );
QCOMPARE( exp.evaluate().toInt(), 1 );

// Load expressions from project
// Project registers 2 functions: mychoice (overwriting it) and myprojectfunction
const QByteArray projectPath = QByteArray( TEST_DATA_DIR ) + "/projects/test_project_functions.qgz";
QgsProject::instance()->read( projectPath );
QCOMPARE( QgsExpression::functionIndex( QStringLiteral( "myprojectfunction" ) ), -1 );
QgsExpression::loadFunctionsFromProject();
QVERIFY( QgsExpression::functionIndex( QStringLiteral( "myprojectfunction" ) ) != -1 );
QVERIFY( QgsExpression::functionIndex( QStringLiteral( "mychoice" ) ) != -1 ); // Overwritten function
const int count_project_loaded = QgsExpression::functionCount();

QCOMPARE( count_project_loaded - count_before_project, 1 ); // myprojectfunction

exp = myExpression; // Re-parse it
QCOMPARE( exp.evaluate().toInt(), 2 ); // Different result because now it's from project

// Unload expressions from project, reload user ones
QgsExpression::cleanFunctionsFromProject();
const int count_project_unloaded = QgsExpression::functionCount();
QCOMPARE( count_before_project, count_project_unloaded ); // myprojectfunction is gone

QCOMPARE( QgsExpression::functionIndex( QStringLiteral( "myprojectfunction" ) ), -1 );
exp = myExpression; // Re-parse it
QCOMPARE( exp.evaluate().toInt(), 1 ); // Original result, coming from user function
}


QGSTEST_MAIN( TestQgsProjectExpressions )
#include "testqgsprojectexpressions.moc"
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from qgis.core import qgsfunction


@qgsfunction(group='Custom', referenced_columns=[])
def mychoice(value1, value2):
return value1
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from qgis.core import qgsfunction


@qgsfunction(group='Custom', referenced_columns=[])
def mychoice2(value1, value2):
return value1 + value2

0 comments on commit fb0cafd

Please sign in to comment.