Skip to content

Commit

Permalink
Expand model unit test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jun 21, 2017
1 parent 065c984 commit 86f33c6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 11 deletions.
4 changes: 2 additions & 2 deletions python/core/processing/qgsprocessingmodelalgorithm.sip
Expand Up @@ -282,9 +282,9 @@ Copies are protected to avoid slicing
%End
public:

ModelOutput( const QString &description = QString() );
ModelOutput( const QString &name = QString(), const QString &description = QString() );
%Docstring
Constructor for ModelOutput with the specified ``description``.
Constructor for ModelOutput with the specified ``name`` and ``description``.
%End

QString childId() const;
Expand Down
29 changes: 22 additions & 7 deletions src/core/processing/qgsprocessingmodelalgorithm.cpp
Expand Up @@ -131,6 +131,11 @@ QgsProcessingModelAlgorithm::ModelOutput &QgsProcessingModelAlgorithm::ChildAlgo
void QgsProcessingModelAlgorithm::ChildAlgorithm::setModelOutputs( const QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> &modelOutputs )
{
mModelOutputs = modelOutputs;
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::iterator outputIt = mModelOutputs.begin();
for ( ; outputIt != mModelOutputs.end(); ++outputIt )
{
outputIt->setChildId( mId );
}
}

QVariant QgsProcessingModelAlgorithm::ChildAlgorithm::toVariant() const
Expand Down Expand Up @@ -319,15 +324,24 @@ QVariantMap QgsProcessingModelAlgorithm::parametersForChildAlgorithm( const Chil
else
{
const QgsProcessingDestinationParameter *destParam = static_cast< const QgsProcessingDestinationParameter * >( def );

// is destination linked to one of the final outputs from this model?
if ( child.modelOutputs().contains( destParam->name() ) )
bool isFinalOutput = false;
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs = child.modelOutputs();
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput>::const_iterator outputIt = outputs.constBegin();
for ( ; outputIt != outputs.constEnd(); ++outputIt )
{
QString outputName = child.modelOutputs().value( destParam->name() ).outputName();
QString paramName = child.childId() + ':' + outputName;
if ( modelParameters.contains( paramName ) )
childParams.insert( destParam->name(), modelParameters.value( paramName ) );
if ( outputIt->outputName() == destParam->name() )
{
QString paramName = child.childId() + ':' + outputIt.key();
if ( modelParameters.contains( paramName ) )
childParams.insert( destParam->name(), modelParameters.value( paramName ) );
isFinalOutput = true;
break;
}
}
else

if ( !isFinalOutput )
{
// output is temporary

Expand Down Expand Up @@ -953,8 +967,9 @@ bool QgsProcessingModelAlgorithm::ChildParameterSource::loadVariant( const QVari
return true;
}

QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &description )
QgsProcessingModelAlgorithm::ModelOutput::ModelOutput( const QString &name, const QString &description )
: QgsProcessingModelAlgorithm::Component( description )
, mOutputName( name )
{}

QVariant QgsProcessingModelAlgorithm::ModelOutput::toVariant() const
Expand Down
4 changes: 2 additions & 2 deletions src/core/processing/qgsprocessingmodelalgorithm.h
Expand Up @@ -285,9 +285,9 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
public:

/**
* Constructor for ModelOutput with the specified \a description.
* Constructor for ModelOutput with the specified \a name and \a description.
*/
ModelOutput( const QString &description = QString() );
ModelOutput( const QString &name = QString(), const QString &description = QString() );

/**
* Returns the child algorithm ID from which this output is generated.
Expand Down
77 changes: 77 additions & 0 deletions tests/src/core/testqgsprocessing.cpp
Expand Up @@ -330,6 +330,7 @@ class TestQgsProcessing: public QObject
void generateIteratingDestination();
void asPythonCommand();
void modelerAlgorithm();
void modelExecution();
void tempUtils();

private:
Expand Down Expand Up @@ -3841,6 +3842,82 @@ void TestQgsProcessing::modelerAlgorithm()
QCOMPARE( alg7.outputDefinitions().at( 0 )->description(), QStringLiteral( "my output2" ) );
}

void TestQgsProcessing::modelExecution()
{
// test childOutputIsRequired
QgsProcessingModelAlgorithm model1;
QgsProcessingModelAlgorithm::ChildAlgorithm algc1;
algc1.setChildId( "cx1" );
algc1.setAlgorithmId( "native:centroids" );
model1.addChildAlgorithm( algc1 );
QgsProcessingModelAlgorithm::ChildAlgorithm algc2;
algc2.setChildId( "cx2" );
algc2.setAlgorithmId( "native:centroids" );
algc2.addParameterSource( "x", QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "cx1", "p1" ) );
model1.addChildAlgorithm( algc2 );
QgsProcessingModelAlgorithm::ChildAlgorithm algc3;
algc3.setChildId( "cx3" );
algc3.setAlgorithmId( "native:centroids" );
algc3.addParameterSource( "x", QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "cx1", "p2" ) );
algc3.setActive( false );
model1.addChildAlgorithm( algc3 );

QVERIFY( model1.childOutputIsRequired( "cx1", "p1" ) ); // cx2 depends on p1
QVERIFY( !model1.childOutputIsRequired( "cx1", "p2" ) ); // cx3 depends on p2, but cx3 is not active
QVERIFY( !model1.childOutputIsRequired( "cx1", "p3" ) ); // nothing requires p3
QVERIFY( !model1.childOutputIsRequired( "cx2", "p1" ) );
QVERIFY( !model1.childOutputIsRequired( "cx3", "p1" ) );

// test parametersForChildAlgorithm
QgsProcessingModelAlgorithm model2;
model2.addModelParameter( new QgsProcessingParameterFeatureSource( "SOURCE_LAYER" ), QgsProcessingModelAlgorithm::ModelParameter( "SOURCE_LAYER" ) );
model2.addModelParameter( new QgsProcessingParameterNumber( "DIST", QString(), QgsProcessingParameterNumber::Double ), QgsProcessingModelAlgorithm::ModelParameter( "DIST" ) );
QgsProcessingModelAlgorithm::ChildAlgorithm alg2c1;
alg2c1.setChildId( "cx1" );
alg2c1.setAlgorithmId( "native:buffer" );
alg2c1.addParameterSource( "INPUT", QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "SOURCE_LAYER" ) );
alg2c1.addParameterSource( "DISTANCE", QgsProcessingModelAlgorithm::ChildParameterSource::fromModelParameter( "DIST" ) );
alg2c1.addParameterSource( "SEGMENTS", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 16 ) );
alg2c1.addParameterSource( "END_CAP_STYLE", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 1 ) );
alg2c1.addParameterSource( "JOIN_STYLE", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( 2 ) );
alg2c1.addParameterSource( "DISSOLVE", QgsProcessingModelAlgorithm::ChildParameterSource::fromStaticValue( false ) );
QMap<QString, QgsProcessingModelAlgorithm::ModelOutput> outputs1;
QgsProcessingModelAlgorithm::ModelOutput out1( "OUTPUT_LAYER" );
outputs1.insert( QStringLiteral( "MODEL_OUT_LAYER" ), out1 );
alg2c1.setModelOutputs( outputs1 );
model2.addChildAlgorithm( alg2c1 );

QVariantMap modelInputs;
modelInputs.insert( "SOURCE_LAYER", "my_layer_id" );
modelInputs.insert( "DIST", 271 );
modelInputs.insert( "cx1:MODEL_OUT_LAYER", "dest.shp" );
QMap<QString, QVariantMap> childResults;
QVariantMap params = model2.parametersForChildAlgorithm( model2.childAlgorithm( "cx1" ), modelInputs, childResults );
QCOMPARE( params.value( "DISSOLVE" ).toBool(), false );
QCOMPARE( params.value( "DISTANCE" ).toInt(), 271 );
QCOMPARE( params.value( "SEGMENTS" ).toInt(), 16 );
QCOMPARE( params.value( "END_CAP_STYLE" ).toInt(), 1 );
QCOMPARE( params.value( "JOIN_STYLE" ).toInt(), 2 );
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "my_layer_id" ) );
QCOMPARE( params.value( "OUTPUT_LAYER" ).toString(), QStringLiteral( "dest.shp" ) );
QCOMPARE( params.count(), 7 );

QVariantMap results;
results.insert( "OUTPUT_LAYER", QStringLiteral( "dest.shp" ) );
childResults.insert( "cx1", results );

// a child who uses an output from another alg as a parameter value
QgsProcessingModelAlgorithm::ChildAlgorithm alg2c2;
alg2c2.setChildId( "cx2" );
alg2c2.setAlgorithmId( "native:centroids" );
alg2c2.addParameterSource( "INPUT", QgsProcessingModelAlgorithm::ChildParameterSource::fromChildOutput( "cx1", "OUTPUT_LAYER" ) );
model2.addChildAlgorithm( alg2c2 );
params = model2.parametersForChildAlgorithm( model2.childAlgorithm( "cx2" ), modelInputs, childResults );
QCOMPARE( params.value( "INPUT" ).toString(), QStringLiteral( "dest.shp" ) );
QCOMPARE( params.value( "OUTPUT_LAYER" ).toString(), QStringLiteral( "memory:" ) );
QCOMPARE( params.count(), 2 );
}

void TestQgsProcessing::tempUtils()
{
QString tempFolder = QgsProcessingUtils::tempFolder();
Expand Down

0 comments on commit 86f33c6

Please sign in to comment.