diff --git a/python/core/auto_additions/qgsprocessingcontext.py b/python/core/auto_additions/qgsprocessingcontext.py new file mode 100644 index 000000000000..cd3a8731da73 --- /dev/null +++ b/python/core/auto_additions/qgsprocessingcontext.py @@ -0,0 +1,5 @@ +# The following has been generated automatically from src/core/processing/qgsprocessingcontext.h +# monkey patching scoped based enum +QgsProcessingContext.ProcessArgumentFlag.IncludeProjectPath.__doc__ = "Include the associated project path argument" +QgsProcessingContext.ProcessArgumentFlag.__doc__ = 'Flags controlling the results given by :py:func:`~QgsProcessingContext.asQgisProcessArguments`.\n\n.. versionadded:: 3.24\n\n' + '* ``IncludeProjectPath``: ' + QgsProcessingContext.ProcessArgumentFlag.IncludeProjectPath.__doc__ +# -- diff --git a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in index 36cbdcd63844..1201617dd22c 100644 --- a/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingalgorithm.sip.in @@ -443,6 +443,30 @@ using the specified ``parameters``. Algorithms which cannot be run from a Python command should return an empty string. +%End + + virtual QString asQgisProcessCommand( const QVariantMap ¶meters, QgsProcessingContext &context, bool &ok /Out/ ) const; +%Docstring +Returns a command string which will execute the algorithm using the specified ``parameters`` +via the command line qgis_process tool. + +Note that some combinations of parameter types and values cannot be represented as a qgis_process string. + +:param parameters: algorithm parameters +:param context: processing context + +:return: - equivalent qgis_process command + - ok: will be set to ``True`` if the command was successfully generated + + +.. versionadded:: 3.24 +%End + + virtual QVariantMap asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const; +%Docstring +Returns a JSON serializable variant map containing the specified ``parameters`` and ``context`` settings. + +.. versionadded:: 3.24 %End void setProvider( QgsProcessingProvider *provider ); diff --git a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in index 796c5a280ce9..8cdd1398c35f 100644 --- a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in @@ -585,6 +585,27 @@ Sets the logging ``level`` for algorithms to use when pushing feedback messages .. seealso:: :py:func:`logLevel` .. versionadded:: 3.20 +%End + + QVariantMap exportToMap() const; +%Docstring +Exports the context's settings to a variant map. + +.. versionadded:: 3.24 +%End + + enum class ProcessArgumentFlag + { + IncludeProjectPath, + }; + typedef QFlags ProcessArgumentFlags; + + + QStringList asQgisProcessArguments( QgsProcessingContext::ProcessArgumentFlags flags = QgsProcessingContext::ProcessArgumentFlags() ) const; +%Docstring +Returns list of the equivalent qgis_process arguments representing the settings from the context. + +.. versionadded:: 3.24 %End private: @@ -593,6 +614,8 @@ Sets the logging ``level`` for algorithms to use when pushing feedback messages QFlags operator|(QgsProcessingContext::Flag f1, QFlags f2); +QFlags operator|(QgsProcessingContext::ProcessArgumentFlag f1, QFlags f2); + class QgsProcessingLayerPostProcessorInterface diff --git a/python/core/auto_generated/processing/qgsprocessingparameters.sip.in b/python/core/auto_generated/processing/qgsprocessingparameters.sip.in index 964834ba89a3..ee1abda2c90a 100644 --- a/python/core/auto_generated/processing/qgsprocessingparameters.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingparameters.sip.in @@ -515,6 +515,63 @@ layers and other factors within the context. %Docstring Returns a string version of the parameter input ``value``, which is suitable for use as an input parameter value when running an algorithm directly from a Python command. + +.. seealso:: :py:func:`valueAsJsonObject` + +.. seealso:: :py:func:`valueAsString` +%End + + virtual QVariant valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const; +%Docstring +Returns a version of the parameter input ``value``, which is suitable for use in a JSON object. + +This method must return only simple values which can be losslessly encapsulated in a serialized +JSON map. For instance, any QGIS class values (such as :py:class:`QgsCoordinateReferenceSystem`) must be +converted to a simple string or numeric value equivalent. + +.. seealso:: :py:func:`valueAsPythonString` + +.. seealso:: :py:func:`valueAsString` + +.. versionadded:: 3.24 +%End + + virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const; +%Docstring +Returns a string version of the parameter input ``value`` (if possible). + +:param value: value to convert +:param context: processing context + +:return: - value converted to string + - ok: will be set to ``True`` if value could be represented as a string. + +.. seealso:: :py:func:`valueAsStringList` + +.. seealso:: :py:func:`valueAsJsonObject` + +.. seealso:: :py:func:`valueAsPythonString` + +.. versionadded:: 3.24 +%End + + virtual QStringList valueAsStringList( const QVariant &value, QgsProcessingContext &context, bool &ok /Out/ ) const; +%Docstring +Returns a string list version of the parameter input ``value`` (if possible). + +:param value: value to convert +:param context: processing context + +:return: - value converted to string list + - ok: will be set to ``True`` if value could be represented as a string list + +.. seealso:: :py:func:`valueAsString` + +.. seealso:: :py:func:`valueAsJsonObject` + +.. seealso:: :py:func:`valueAsPythonString` + +.. versionadded:: 3.24 %End virtual QString valueAsPythonComment( const QVariant &value, QgsProcessingContext &context ) const; diff --git a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in index 33eed64d2567..e14e69ba9177 100644 --- a/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in +++ b/python/gui/auto_generated/processing/qgsprocessingalgorithmdialogbase.sip.in @@ -131,6 +131,13 @@ Sets the logging ``level`` to use when running algorithms from the dialog. .. seealso:: :py:func:`logLevel` .. versionadded:: 3.20 +%End + + virtual void setParameters( const QVariantMap &values ); +%Docstring +Sets the parameter ``values`` to show in the dialog. + +.. versionadded:: 3.24 %End public slots: diff --git a/src/core/processing/qgsprocessingalgorithm.cpp b/src/core/processing/qgsprocessingalgorithm.cpp index 489075e4c883..533e6cf97b61 100644 --- a/src/core/processing/qgsprocessingalgorithm.cpp +++ b/src/core/processing/qgsprocessingalgorithm.cpp @@ -306,6 +306,64 @@ QString QgsProcessingAlgorithm::asPythonCommand( const QVariantMap ¶meters, return s; } +QString QgsProcessingAlgorithm::asQgisProcessCommand( const QVariantMap ¶meters, QgsProcessingContext &context, bool &ok ) const +{ + ok = true; + QStringList parts; + parts.append( QStringLiteral( "qgis_process" ) ); + parts.append( QStringLiteral( "run" ) ); + parts.append( id() ); + + QgsProcessingContext::ProcessArgumentFlags argumentFlags; + // we only include the project path argument if a project is actually required by the algorithm + if ( flags() & FlagRequiresProject ) + argumentFlags |= QgsProcessingContext::ProcessArgumentFlag::IncludeProjectPath; + + parts.append( context.asQgisProcessArguments( argumentFlags ) ); + + for ( const QgsProcessingParameterDefinition *def : mParameters ) + { + if ( def->flags() & QgsProcessingParameterDefinition::FlagHidden ) + continue; + + if ( !parameters.contains( def->name() ) ) + continue; + + const QStringList partValues = def->valueAsStringList( parameters.value( def->name() ), context, ok ); + if ( !ok ) + return QString(); + + for ( const QString &partValue : partValues ) + parts << QStringLiteral( "--%1=%2" ).arg( def->name(), partValue ); + } + + return parts.join( ' ' ); +} + +QVariantMap QgsProcessingAlgorithm::asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const +{ + QVariantMap properties = context.exportToMap(); + + // we only include the project path argument if a project is actually required by the algorithm + if ( !( flags() & FlagRequiresProject ) ) + properties.remove( QStringLiteral( "project_path" ) ); + + QVariantMap paramValues; + for ( const QgsProcessingParameterDefinition *def : mParameters ) + { + if ( def->flags() & QgsProcessingParameterDefinition::FlagHidden ) + continue; + + if ( !parameters.contains( def->name() ) ) + continue; + + paramValues.insert( def->name(), def->valueAsJsonObject( parameters.value( def->name() ), context ) ); + } + + properties.insert( QStringLiteral( "inputs" ), paramValues ); + return properties; +} + bool QgsProcessingAlgorithm::addParameter( QgsProcessingParameterDefinition *definition, bool createOutput ) { if ( !definition ) diff --git a/src/core/processing/qgsprocessingalgorithm.h b/src/core/processing/qgsprocessingalgorithm.h index b906fc99c4a4..a37508905c57 100644 --- a/src/core/processing/qgsprocessingalgorithm.h +++ b/src/core/processing/qgsprocessingalgorithm.h @@ -461,6 +461,29 @@ class CORE_EXPORT QgsProcessingAlgorithm */ virtual QString asPythonCommand( const QVariantMap ¶meters, QgsProcessingContext &context ) const; + /** + * Returns a command string which will execute the algorithm using the specified \a parameters + * via the command line qgis_process tool. + * + * Note that some combinations of parameter types and values cannot be represented as a qgis_process string. + * + * \param parameters algorithm parameters + * \param context processing context + * \param ok will be set to TRUE if the command was successfully generated + * + * \returns equivalent qgis_process command + * + * \since QGIS 3.24 + */ + virtual QString asQgisProcessCommand( const QVariantMap ¶meters, QgsProcessingContext &context, bool &ok SIP_OUT ) const; + + /** + * Returns a JSON serializable variant map containing the specified \a parameters and \a context settings. + * + * \since QGIS 3.24 + */ + virtual QVariantMap asMap( const QVariantMap ¶meters, QgsProcessingContext &context ) const; + /** * Associates this algorithm with its provider. No transfer of ownership is involved. */ diff --git a/src/core/processing/qgsprocessingcontext.cpp b/src/core/processing/qgsprocessingcontext.cpp index 4c52a4c46a06..daeec0adc0a7 100644 --- a/src/core/processing/qgsprocessingcontext.cpp +++ b/src/core/processing/qgsprocessingcontext.cpp @@ -139,6 +139,39 @@ void QgsProcessingContext::setLogLevel( LogLevel level ) mLogLevel = level; } +QVariantMap QgsProcessingContext::exportToMap() const +{ + QVariantMap res; + if ( mDistanceUnit != QgsUnitTypes::DistanceUnknownUnit ) + res.insert( QStringLiteral( "distance_units" ), QgsUnitTypes::encodeUnit( mDistanceUnit ) ); + if ( mAreaUnit != QgsUnitTypes::AreaUnknownUnit ) + res.insert( QStringLiteral( "area_units" ), QgsUnitTypes::encodeUnit( mAreaUnit ) ); + if ( !mEllipsoid.isEmpty() ) + res.insert( QStringLiteral( "ellipsoid" ), mEllipsoid ); + if ( mProject ) + res.insert( QStringLiteral( "project_path" ), mProject->fileName() ); + + return res; +} + +QStringList QgsProcessingContext::asQgisProcessArguments( QgsProcessingContext::ProcessArgumentFlags flags ) const +{ + QStringList res; + if ( mDistanceUnit != QgsUnitTypes::DistanceUnknownUnit ) + res << QStringLiteral( "--distance_units=%1" ).arg( QgsUnitTypes::encodeUnit( mDistanceUnit ) ); + if ( mAreaUnit != QgsUnitTypes::AreaUnknownUnit ) + res << QStringLiteral( "--area_units=%1" ).arg( QgsUnitTypes::encodeUnit( mAreaUnit ) ); + if ( !mEllipsoid.isEmpty() ) + res << QStringLiteral( "--ellipsoid=%1" ).arg( mEllipsoid ); + + if ( mProject && flags & ProcessArgumentFlag::IncludeProjectPath ) + { + res << QStringLiteral( "--project_path=%1" ).arg( mProject->fileName() ); + } + + return res; +} + QgsDateTimeRange QgsProcessingContext::currentTimeRange() const { return mCurrentTimeRange; diff --git a/src/core/processing/qgsprocessingcontext.h b/src/core/processing/qgsprocessingcontext.h index 77831bb71dfe..99f7a620cbb8 100644 --- a/src/core/processing/qgsprocessingcontext.h +++ b/src/core/processing/qgsprocessingcontext.h @@ -657,6 +657,31 @@ class CORE_EXPORT QgsProcessingContext */ void setLogLevel( LogLevel level ); + /** + * Exports the context's settings to a variant map. + * + * \since QGIS 3.24 + */ + QVariantMap exportToMap() const; + + /** + * Flags controlling the results given by asQgisProcessArguments(). + * + * \since QGIS 3.24 + */ + enum class ProcessArgumentFlag : int + { + IncludeProjectPath = 1 << 0, //!< Include the associated project path argument + }; + Q_DECLARE_FLAGS( ProcessArgumentFlags, ProcessArgumentFlag ) + + /** + * Returns list of the equivalent qgis_process arguments representing the settings from the context. + * + * \since QGIS 3.24 + */ + QStringList asQgisProcessArguments( QgsProcessingContext::ProcessArgumentFlags flags = QgsProcessingContext::ProcessArgumentFlags() ) const; + private: QgsProcessingContext::Flags mFlags = QgsProcessingContext::Flags(); @@ -694,6 +719,7 @@ class CORE_EXPORT QgsProcessingContext }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProcessingContext::Flags ) +Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProcessingContext::ProcessArgumentFlags ) /** diff --git a/src/core/processing/qgsprocessingparameters.cpp b/src/core/processing/qgsprocessingparameters.cpp index 5a39c3c37438..fc24216ad6d3 100644 --- a/src/core/processing/qgsprocessingparameters.cpp +++ b/src/core/processing/qgsprocessingparameters.cpp @@ -2449,6 +2449,406 @@ QString QgsProcessingParameterDefinition::valueAsPythonString( const QVariant &v return QgsProcessingUtils::stringToPythonLiteral( value.toString() ); } +QVariant QgsProcessingParameterDefinition::valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const +{ + if ( !value.isValid() ) + return value; + + // dive into map and list types and convert each value + if ( value.type() == QVariant::Type::Map ) + { + const QVariantMap sourceMap = value.toMap(); + QVariantMap resultMap; + for ( auto it = sourceMap.constBegin(); it != sourceMap.constEnd(); it++ ) + { + resultMap[ it.key() ] = valueAsJsonObject( it.value(), context ); + } + return resultMap; + } + else if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList ) + { + const QVariantList sourceList = value.toList(); + QVariantList resultList; + resultList.reserve( sourceList.size() ); + for ( const QVariant &v : sourceList ) + { + resultList.push_back( valueAsJsonObject( v, context ) ); + } + return resultList; + } + else + { + switch ( value.userType() ) + { + // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet! + case QMetaType::Bool: + case QMetaType::Char: + case QMetaType::Int: + case QMetaType::Double: + case QMetaType::Float: + case QMetaType::LongLong: + case QMetaType::ULongLong: + case QMetaType::UInt: + case QMetaType::ULong: + case QMetaType::UShort: + return value; + + default: + break; + } + + + if ( value.userType() == QMetaType::type( "QgsProperty" ) ) + { + const QgsProperty prop = value.value< QgsProperty >(); + switch ( prop.propertyType() ) + { + case QgsProperty::InvalidProperty: + return QVariant(); + case QgsProperty::StaticProperty: + return valueAsJsonObject( prop.staticValue(), context ); + + // these are not supported for serialization + case QgsProperty::FieldBasedProperty: + case QgsProperty::ExpressionBasedProperty: + QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to JSON object" ) ); + return QVariant(); + } + } + + // value may be a CRS + if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) ) + { + const QgsCoordinateReferenceSystem crs = value.value< QgsCoordinateReferenceSystem >(); + if ( !crs.isValid() ) + return QString(); + else if ( !crs.authid().isEmpty() ) + return crs.authid(); + else + return crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ); + } + else if ( value.userType() == QMetaType::type( "QgsRectangle" ) ) + { + const QgsRectangle r = value.value(); + return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ), + qgsDoubleToString( r.yMinimum() ), + qgsDoubleToString( r.xMaximum() ), + qgsDoubleToString( r.yMaximum() ) ); + } + else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) ) + { + const QgsReferencedRectangle r = value.value(); + return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ), + qgsDoubleToString( r.yMinimum() ), + qgsDoubleToString( r.xMaximum() ), + qgsDoubleToString( r.yMaximum() ), r.crs().authid() ); + } + else if ( value.userType() == QMetaType::type( "QgsGeometry" ) ) + { + const QgsGeometry g = value.value(); + if ( !g.isNull() ) + { + return g.asWkt(); + } + else + { + return QString(); + } + } + else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) ) + { + const QgsReferencedGeometry g = value.value(); + if ( !g.isNull() ) + { + if ( !g.crs().isValid() ) + return g.asWkt(); + else + return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() ); + } + else + { + return QString(); + } + } + else if ( value.userType() == QMetaType::type( "QgsPointXY" ) ) + { + const QgsPointXY r = value.value(); + return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ), + qgsDoubleToString( r.y() ) ); + } + else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) ) + { + const QgsReferencedPointXY r = value.value(); + return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ), + qgsDoubleToString( r.y() ), + r.crs().authid() ); + } + else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) ) + { + const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast( value ); + + // TODO -- we could consider also serializating the additional properties like invalid feature handling, limits, etc + return valueAsJsonObject( fromVar.source, context ); + } + else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) ) + { + const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); + return valueAsJsonObject( fromVar.sink, context ); + } + else if ( value.userType() == QMetaType::type( "QColor" ) ) + { + const QColor fromVar = value.value< QColor >(); + if ( !fromVar.isValid() ) + return QString(); + + return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) ); + } + else if ( value.userType() == QMetaType::type( "QDateTime" ) ) + { + const QDateTime fromVar = value.toDateTime(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + else if ( value.userType() == QMetaType::type( "QDate" ) ) + { + const QDate fromVar = value.toDate(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + else if ( value.userType() == QMetaType::type( "QTime" ) ) + { + const QTime fromVar = value.toTime(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + + // value may be a map layer + QVariantMap p; + p.insert( name(), value ); + if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) ) + { + const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() ); + if ( !source.isEmpty() ) + return source; + return layer->id(); + } + + // now we handle strings, after any other specific logic has already been applied + if ( value.userType() == QMetaType::QString ) + return value; + } + + // unhandled type + Q_ASSERT_X( false, "QgsProcessingParameterDefinition::valueAsJsonObject", QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ).toLocal8Bit() ); + return value; +} + +QString QgsProcessingParameterDefinition::valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok ) const +{ + ok = true; + + if ( !value.isValid() ) + return QString(); + + switch ( value.userType() ) + { + // simple types which can be directly represented in JSON -- note that strings are NOT handled here yet! + case QMetaType::Bool: + case QMetaType::Char: + case QMetaType::Int: + case QMetaType::Double: + case QMetaType::Float: + case QMetaType::LongLong: + case QMetaType::ULongLong: + case QMetaType::UInt: + case QMetaType::ULong: + case QMetaType::UShort: + return value.toString(); + + default: + break; + } + + if ( value.userType() == QMetaType::type( "QgsProperty" ) ) + { + const QgsProperty prop = value.value< QgsProperty >(); + switch ( prop.propertyType() ) + { + case QgsProperty::InvalidProperty: + return QString(); + case QgsProperty::StaticProperty: + return valueAsString( prop.staticValue(), context, ok ); + + // these are not supported for serialization + case QgsProperty::FieldBasedProperty: + case QgsProperty::ExpressionBasedProperty: + QgsDebugMsg( QStringLiteral( "could not convert expression/field based property to string" ) ); + return QString(); + } + } + + // value may be a CRS + if ( value.userType() == QMetaType::type( "QgsCoordinateReferenceSystem" ) ) + { + const QgsCoordinateReferenceSystem crs = value.value< QgsCoordinateReferenceSystem >(); + if ( !crs.isValid() ) + return QString(); + else if ( !crs.authid().isEmpty() ) + return crs.authid(); + else + return crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ); + } + else if ( value.userType() == QMetaType::type( "QgsRectangle" ) ) + { + const QgsRectangle r = value.value(); + return QStringLiteral( "%1, %3, %2, %4" ).arg( qgsDoubleToString( r.xMinimum() ), + qgsDoubleToString( r.yMinimum() ), + qgsDoubleToString( r.xMaximum() ), + qgsDoubleToString( r.yMaximum() ) ); + } + else if ( value.userType() == QMetaType::type( "QgsReferencedRectangle" ) ) + { + const QgsReferencedRectangle r = value.value(); + return QStringLiteral( "%1, %3, %2, %4 [%5]" ).arg( qgsDoubleToString( r.xMinimum() ), + qgsDoubleToString( r.yMinimum() ), + qgsDoubleToString( r.xMaximum() ), + qgsDoubleToString( r.yMaximum() ), r.crs().authid() ); + } + else if ( value.userType() == QMetaType::type( "QgsGeometry" ) ) + { + const QgsGeometry g = value.value(); + if ( !g.isNull() ) + { + return g.asWkt(); + } + else + { + return QString(); + } + } + else if ( value.userType() == QMetaType::type( "QgsReferencedGeometry" ) ) + { + const QgsReferencedGeometry g = value.value(); + if ( !g.isNull() ) + { + if ( !g.crs().isValid() ) + return g.asWkt(); + else + return QStringLiteral( "CRS=%1;%2" ).arg( g.crs().authid().isEmpty() ? g.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : g.crs().authid(), g.asWkt() ); + } + else + { + return QString(); + } + } + else if ( value.userType() == QMetaType::type( "QgsPointXY" ) ) + { + const QgsPointXY r = value.value(); + return QStringLiteral( "%1,%2" ).arg( qgsDoubleToString( r.x() ), + qgsDoubleToString( r.y() ) ); + } + else if ( value.userType() == QMetaType::type( "QgsReferencedPointXY" ) ) + { + const QgsReferencedPointXY r = value.value(); + return QStringLiteral( "%1,%2 [%3]" ).arg( qgsDoubleToString( r.x() ), + qgsDoubleToString( r.y() ), + r.crs().authid() ); + } + else if ( value.userType() == QMetaType::type( "QgsProcessingFeatureSourceDefinition" ) ) + { + const QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast( value ); + return valueAsString( fromVar.source, context, ok ); + } + else if ( value.userType() == QMetaType::type( "QgsProcessingOutputLayerDefinition" ) ) + { + const QgsProcessingOutputLayerDefinition fromVar = qvariant_cast( value ); + return valueAsString( fromVar.sink, context, ok ); + } + else if ( value.userType() == QMetaType::type( "QColor" ) ) + { + const QColor fromVar = value.value< QColor >(); + if ( !fromVar.isValid() ) + return QString(); + + return QStringLiteral( "rgba( %1, %2, %3, %4 )" ).arg( fromVar.red() ).arg( fromVar.green() ).arg( fromVar.blue() ).arg( QString::number( fromVar.alphaF(), 'f', 2 ) ); + } + else if ( value.userType() == QMetaType::type( "QDateTime" ) ) + { + const QDateTime fromVar = value.toDateTime(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + else if ( value.userType() == QMetaType::type( "QDate" ) ) + { + const QDate fromVar = value.toDate(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + else if ( value.userType() == QMetaType::type( "QTime" ) ) + { + const QTime fromVar = value.toTime(); + if ( !fromVar.isValid() ) + return QString(); + + return fromVar.toString( Qt::ISODate ); + } + + // value may be a map layer + QVariantMap p; + p.insert( name(), value ); + if ( QgsMapLayer *layer = QgsProcessingParameters::parameterAsLayer( this, p, context ) ) + { + const QString source = QgsProcessingUtils::normalizeLayerSource( layer->source() ); + if ( !source.isEmpty() ) + return source; + return layer->id(); + } + + // now we handle strings, after any other specific logic has already been applied + if ( value.userType() == QMetaType::QString ) + return value.toString(); + + // unhandled type + QgsDebugMsg( QStringLiteral( "unsupported variant type %1" ).arg( QMetaType::typeName( value.userType() ) ) ); + ok = false; + return value.toString(); +} + +QStringList QgsProcessingParameterDefinition::valueAsStringList( const QVariant &value, QgsProcessingContext &context, bool &ok ) const +{ + ok = true; + if ( !value.isValid( ) ) + return QStringList(); + + if ( value.type() == QVariant::Type::List || value.type() == QVariant::Type::StringList ) + { + const QVariantList sourceList = value.toList(); + QStringList resultList; + resultList.reserve( sourceList.size() ); + for ( const QVariant &v : sourceList ) + { + resultList.append( valueAsStringList( v, context, ok ) ); + } + return resultList; + } + + const QString res = valueAsString( value, context, ok ); + if ( !ok ) + return QStringList(); + + return {res}; +} + QString QgsProcessingParameterDefinition::valueAsPythonComment( const QVariant &, QgsProcessingContext & ) const { return QString(); diff --git a/src/core/processing/qgsprocessingparameters.h b/src/core/processing/qgsprocessingparameters.h index 1d7f37362f77..6d2560a2f8c7 100644 --- a/src/core/processing/qgsprocessingparameters.h +++ b/src/core/processing/qgsprocessingparameters.h @@ -611,9 +611,55 @@ class CORE_EXPORT QgsProcessingParameterDefinition /** * Returns a string version of the parameter input \a value, which is suitable for use as an input * parameter value when running an algorithm directly from a Python command. + * + * \see valueAsJsonObject() + * \see valueAsString() */ virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const; + /** + * Returns a version of the parameter input \a value, which is suitable for use in a JSON object. + * + * This method must return only simple values which can be losslessly encapsulated in a serialized + * JSON map. For instance, any QGIS class values (such as QgsCoordinateReferenceSystem) must be + * converted to a simple string or numeric value equivalent. + * + * \see valueAsPythonString() + * \see valueAsString() + * \since QGIS 3.24 + */ + virtual QVariant valueAsJsonObject( const QVariant &value, QgsProcessingContext &context ) const; + + /** + * Returns a string version of the parameter input \a value (if possible). + * + * \param value value to convert + * \param context processing context + * \param ok will be set to TRUE if value could be represented as a string. + * \returns value converted to string + * + * \see valueAsStringList() + * \see valueAsJsonObject() + * \see valueAsPythonString() + * \since QGIS 3.24 + */ + virtual QString valueAsString( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const; + + /** + * Returns a string list version of the parameter input \a value (if possible). + * + * \param value value to convert + * \param context processing context + * \param ok will be set to TRUE if value could be represented as a string list + * \returns value converted to string list + * + * \see valueAsString() + * \see valueAsJsonObject() + * \see valueAsPythonString() + * \since QGIS 3.24 + */ + virtual QStringList valueAsStringList( const QVariant &value, QgsProcessingContext &context, bool &ok SIP_OUT ) const; + /** * Returns a Python comment explaining a parameter \a value, or an empty string if no comment is required. * diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp index 57e2a3a4f971..d7fd5b9e736b 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.cpp @@ -25,6 +25,7 @@ #include "qgsstringutils.h" #include "qgsapplication.h" #include "qgspanelwidget.h" +#include "qgsjsonutils.h" #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include ///@cond NOT_STABLE @@ -158,15 +160,98 @@ QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *par } } ); + mCopyAsQgisProcessCommand = new QAction( tr( "Copy as qgis_process Command" ), mAdvancedMenu ); + mCopyAsQgisProcessCommand->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionTerminal.svg" ) ) ); + mAdvancedMenu->addAction( mCopyAsQgisProcessCommand ); + + connect( mCopyAsQgisProcessCommand, &QAction::triggered, this, [this] + { + if ( const QgsProcessingAlgorithm *alg = algorithm() ) + { + QgsProcessingContext *context = processingContext(); + if ( !context ) + return; + + bool ok = false; + const QString command = alg->asQgisProcessCommand( createProcessingParameters(), *context, ok ); + if ( ! ok ) + { + mMessageBar->pushMessage( tr( "Current settings are not compatible with qgis_process" ), Qgis::MessageLevel::Warning ); + } + else + { + QMimeData *m = new QMimeData(); + m->setText( command ); + QClipboard *cb = QApplication::clipboard(); + +#ifdef Q_OS_LINUX + cb->setMimeData( m, QClipboard::Selection ); +#endif + cb->setMimeData( m, QClipboard::Clipboard ); + } + } + } ); + + mAdvancedMenu->addSeparator(); + + QAction *copyAsJson = new QAction( tr( "Copy as JSON" ), mAdvancedMenu ); + copyAsJson->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionEditCopy.svg" ) ) ); + + mAdvancedMenu->addAction( copyAsJson ); + connect( copyAsJson, &QAction::triggered, this, [this] + { + if ( const QgsProcessingAlgorithm *alg = algorithm() ) + { + QgsProcessingContext *context = processingContext(); + if ( !context ) + return; + + const QVariantMap properties = alg->asMap( createProcessingParameters(), *context ); + const QString json = QString::fromStdString( QgsJsonUtils::jsonFromVariant( properties ).dump( 2 ) ); + + QMimeData *m = new QMimeData(); + m->setText( json ); + QClipboard *cb = QApplication::clipboard(); + +#ifdef Q_OS_LINUX + cb->setMimeData( m, QClipboard::Selection ); +#endif + cb->setMimeData( m, QClipboard::Clipboard ); + } + } ); + + mPasteJsonAction = new QAction( tr( "Paste Settings" ), mAdvancedMenu ); + mPasteJsonAction->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionEditPaste.svg" ) ) ); + + mAdvancedMenu->addAction( mPasteJsonAction ); + connect( mPasteJsonAction, &QAction::triggered, this, [this] + { + const QString text = QApplication::clipboard()->text(); + if ( text.isEmpty() ) + return; + + const QVariantMap parameterValues = QgsJsonUtils::parseJson( text ).toMap().value( QStringLiteral( "inputs" ) ).toMap(); + if ( parameterValues.isEmpty() ) + return; + + setParameters( parameterValues ); + } ); + mButtonBox->addButton( mAdvancedButton, QDialogButtonBox::ResetRole ); break; } case DialogMode::Batch: break; - } + connect( mAdvancedMenu, &QMenu::aboutToShow, this, [ = ] + { + mCopyAsQgisProcessCommand->setEnabled( algorithm() + && !( algorithm()->flags() & QgsProcessingAlgorithm::FlagNotAvailableInStandaloneTool ) ); + mPasteJsonAction->setEnabled( !QApplication::clipboard()->text().isEmpty() ); + } ); + connect( mButtonRun, &QPushButton::clicked, this, &QgsProcessingAlgorithmDialogBase::runAlgorithm ); connect( mButtonChangeParameters, &QPushButton::clicked, this, &QgsProcessingAlgorithmDialogBase::showParameters ); connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsProcessingAlgorithmDialogBase::closeClicked ); @@ -189,6 +274,9 @@ QgsProcessingAlgorithmDialogBase::QgsProcessingAlgorithmDialogBase( QWidget *par QgsProcessingAlgorithmDialogBase::~QgsProcessingAlgorithmDialogBase() = default; +void QgsProcessingAlgorithmDialogBase::setParameters( const QVariantMap & ) +{} + void QgsProcessingAlgorithmDialogBase::setAlgorithm( QgsProcessingAlgorithm *algorithm ) { mAlgorithm.reset( algorithm ); diff --git a/src/gui/processing/qgsprocessingalgorithmdialogbase.h b/src/gui/processing/qgsprocessingalgorithmdialogbase.h index 437c8329e488..13dafd80df73 100644 --- a/src/gui/processing/qgsprocessingalgorithmdialogbase.h +++ b/src/gui/processing/qgsprocessingalgorithmdialogbase.h @@ -191,6 +191,13 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, public QgsPr */ void setLogLevel( QgsProcessingContext::LogLevel level ); + /** + * Sets the parameter \a values to show in the dialog. + * + * \since QGIS 3.24 + */ + virtual void setParameters( const QVariantMap &values ); + public slots: /** @@ -421,6 +428,8 @@ class GUI_EXPORT QgsProcessingAlgorithmDialogBase : public QDialog, public QgsPr QgsMessageBar *mMessageBar = nullptr; QPushButton *mAdvancedButton = nullptr; QMenu *mAdvancedMenu = nullptr; + QAction *mCopyAsQgisProcessCommand = nullptr; + QAction *mPasteJsonAction = nullptr; bool mExecuted = false; bool mExecutedAnyResult = false; diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index 8df608bc9e6c..19e5ccbff656 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -24,6 +24,7 @@ #include "qgsprocessingmodelalgorithm.h" #include "qgsprocessingmodelgroupbox.h" #include "qgsnativealgorithms.h" +#include "qgsconfig.h" #include #include #include @@ -57,7 +58,8 @@ #include "qgsdxfexport.h" #include "qgspointcloudlayer.h" #include "qgsannotationlayer.h" -#include "qgsconfig.h" +#include "qgsjsonutils.h" +#include "json.hpp" class DummyAlgorithm : public QgsProcessingAlgorithm { @@ -343,6 +345,88 @@ class DummyAlgorithm : public QgsProcessingAlgorithm QCOMPARE( asPythonCommand( params, context ), QStringLiteral( "processing.run(\"test\", {'p1':'a','p2':'b'})" ) ); } + void runAsQgisProcessCommandChecks() + { + addParameter( new QgsProcessingParameterString( "p1" ) ); + addParameter( new QgsProcessingParameterEnum( "p2", QString(), QStringList( {"a", "b"} ), true ) ); + QgsProcessingParameterString *hidden = new QgsProcessingParameterString( "p3" ); + hidden->setFlags( QgsProcessingParameterDefinition::FlagHidden ); + addParameter( hidden ); + + QVariantMap params; + QgsProcessingContext context; + + bool ok = false; + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test" ) ); + QVERIFY( ok ); + params.insert( QStringLiteral( "p1" ), "a" ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --p1=a" ) ); + QVERIFY( ok ); + params.insert( QStringLiteral( "p2" ), QVariant() ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --p1=a" ) ); + QVERIFY( ok ); + params.insert( "p2", "b" ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --p1=a --p2=b" ) ); + QVERIFY( ok ); + + params.insert( "p2", QStringList( {"b", "c"} ) ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --p1=a --p2=b --p2=c" ) ); + QVERIFY( ok ); + + // hidden, shouldn't be shown + params.insert( "p3", "b" ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --p1=a --p2=b --p2=c" ) ); + QVERIFY( ok ); + + // test inclusion of a context setting + context.setDistanceUnit( QgsUnitTypes::DistanceMeters ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QStringLiteral( "qgis_process run test --distance_units=meters --p1=a --p2=b --p2=c" ) ); + QVERIFY( ok ); + + // test non-convertible parameter value + params.insert( "p2", QVariant::fromValue( QRectF( 0, 1, 2, 3 ) ) ); + QCOMPARE( asQgisProcessCommand( params, context, ok ), QString() ); + QVERIFY( !ok ); + } + + void runAsAsJsonMapChecks() + { + addParameter( new QgsProcessingParameterString( "p1" ) ); + addParameter( new QgsProcessingParameterEnum( "p2", QString(), QStringList( {"a", "b"} ), true ) ); + QgsProcessingParameterString *hidden = new QgsProcessingParameterString( "p3" ); + hidden->setFlags( QgsProcessingParameterDefinition::FlagHidden ); + addParameter( hidden ); + + QVariantMap params; + QgsProcessingContext context; + + QString res; + QCOMPARE( asMap( params, context ), QVariantMap( { {QStringLiteral( "inputs" ), QVariantMap()}} ) ); + params.insert( QStringLiteral( "p1" ), "a" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\"}}" ) ); + params.insert( QStringLiteral( "p2" ), QVariant() ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":null}}" ) ); + params.insert( "p2", "b" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":\"b\"}}" ) ); + + params.insert( "p2", QStringList( {"b", "c"} ) ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + + // hidden, shouldn't be shown + params.insert( "p3", "b" ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + + // test inclusion of a context setting + context.setDistanceUnit( QgsUnitTypes::DistanceMeters ); + res = QString::fromStdString( QgsJsonUtils::jsonFromVariant( asMap( params, context ) ).dump() ); + QCOMPARE( res, QStringLiteral( "{\"distance_units\":\"meters\",\"inputs\":{\"p1\":\"a\",\"p2\":[\"b\",\"c\"]}}" ) ); + } + void addDestParams() { QgsProcessingParameterFeatureSink *sinkParam1 = new QgsProcessingParameterFeatureSink( "supports" ); @@ -606,6 +690,8 @@ class TestQgsProcessing: public QObject void encodeDecodeUriProvider(); void normalizeLayerSource(); void context(); + void contextToProcessArguments(); + void contextToMap(); void feedback(); void mapLayers(); void mapLayerFromStore(); @@ -683,6 +769,8 @@ class TestQgsProcessing: public QObject void validateInputCrs(); void generateIteratingDestination(); void asPythonCommand(); + void asQgisProcessCommand(); + void asJsonMap(); void modelerAlgorithm(); void modelExecution(); void modelBranchPruning(); @@ -1259,6 +1347,75 @@ void TestQgsProcessing::context() QVERIFY( !context2.temporaryLayerStore()->mapLayer( id ) ); } +void TestQgsProcessing::contextToProcessArguments() +{ + // test converting QgsProcessingContext settings to qgis_process arguments + QgsProcessingContext context; + + QCOMPARE( context.asQgisProcessArguments(), QStringList() ); + context.setDistanceUnit( QgsUnitTypes::DistanceKilometers ); + QCOMPARE( context.asQgisProcessArguments(), QStringList( {QStringLiteral( "--distance_units=km" )} ) ); + + context.setAreaUnit( QgsUnitTypes::AreaHectares ); + QCOMPARE( context.asQgisProcessArguments(), QStringList( {QStringLiteral( "--distance_units=km" ), QStringLiteral( "--area_units=ha" )} ) ); + + context.setEllipsoid( QStringLiteral( "EPSG:7019" ) ); + QCOMPARE( context.asQgisProcessArguments(), QStringList( {QStringLiteral( "--distance_units=km" ), QStringLiteral( "--area_units=ha" ), QStringLiteral( "--ellipsoid=EPSG:7019" )} ) ); + + QgsProject p; + QgsProcessingContext context2; + QVERIFY( p.read( TEST_DATA_DIR + QStringLiteral( "/projects/custom_crs.qgs" ) ) ); + context2.setProject( &p ); + + // by default we don't include the project path argument + QCOMPARE( context2.asQgisProcessArguments(), QStringList( {QStringLiteral( "--distance_units=meters" ), QStringLiteral( "--area_units=m2" ), QStringLiteral( "--ellipsoid=NONE" )} ) ); + + QCOMPARE( context2.asQgisProcessArguments( QgsProcessingContext::ProcessArgumentFlag::IncludeProjectPath ), QStringList( + { + QStringLiteral( "--distance_units=meters" ), QStringLiteral( "--area_units=m2" ), QStringLiteral( "--ellipsoid=NONE" ), + QStringLiteral( "--project_path=%1" ).arg( TEST_DATA_DIR + QStringLiteral( "/projects/custom_crs.qgs" ) ) + } ) ); +} + +void TestQgsProcessing::contextToMap() +{ + // test converting QgsProcessingContext settings to a json map + QgsProcessingContext context; + + QCOMPARE( context.exportToMap(), QVariantMap() ); + context.setDistanceUnit( QgsUnitTypes::DistanceKilometers ); + QCOMPARE( context.exportToMap(), QVariantMap( {{ + QStringLiteral( "distance_units" ), QStringLiteral( "km" ) + }} ) ); + + context.setAreaUnit( QgsUnitTypes::AreaHectares ); + QCOMPARE( context.exportToMap(), QVariantMap( + { + {QStringLiteral( "distance_units" ), QStringLiteral( "km" )}, + {QStringLiteral( "area_units" ), QStringLiteral( "ha" )} + } ) ); + + context.setEllipsoid( QStringLiteral( "EPSG:7019" ) ); + QCOMPARE( context.exportToMap(), QVariantMap( + { + {QStringLiteral( "distance_units" ), QStringLiteral( "km" )}, + {QStringLiteral( "area_units" ), QStringLiteral( "ha" )}, + {QStringLiteral( "ellipsoid" ), QStringLiteral( "EPSG:7019" )}, + } ) ); + + QgsProject p; + QgsProcessingContext context2; + QVERIFY( p.read( TEST_DATA_DIR + QStringLiteral( "/projects/custom_crs.qgs" ) ) ); + context2.setProject( &p ); + QCOMPARE( context2.exportToMap(), QVariantMap( + { + {QStringLiteral( "distance_units" ), QStringLiteral( "meters" )}, + {QStringLiteral( "area_units" ), QStringLiteral( "m2" )}, + {QStringLiteral( "ellipsoid" ), QStringLiteral( "NONE" )}, + {QStringLiteral( "project_path" ), QString( TEST_DATA_DIR + QStringLiteral( "/projects/custom_crs.qgs" ) )} + } ) ); +} + void TestQgsProcessing::feedback() { QgsProcessingFeedback f; @@ -2621,6 +2778,35 @@ void TestQgsProcessing::parameterBoolean() QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterBoolean('non_optional_default_false', '', defaultValue=None)" ) ); + QCOMPARE( def->valueAsJsonObject( false, context ), QVariant( false ) ); + QCOMPARE( def->valueAsJsonObject( true, context ), QVariant( true ) ); + QCOMPARE( def->valueAsJsonObject( "false", context ), QVariant( QStringLiteral( "false" ) ) ); + QCOMPARE( def->valueAsJsonObject( "true", context ), QVariant( QStringLiteral( "true" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + + bool ok = false; + QCOMPARE( def->valueAsString( false, context, ok ), QStringLiteral( "false" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( true, context, ok ), QStringLiteral( "true" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "false", context, ok ), QStringLiteral( "false" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "true", context, ok ), QStringLiteral( "true" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + + QCOMPARE( def->valueAsStringList( false, context, ok ), QStringList( {QStringLiteral( "false" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( true, context, ok ), QStringList( {QStringLiteral( "true" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( "false", context, ok ), QStringList( {QStringLiteral( "false" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( "true", context, ok ), QStringList( {QStringLiteral( "true" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariant(), context, ok ), QStringList() ); + QVERIFY( ok ); + QString code = def->asScriptCode(); QCOMPARE( code, QStringLiteral( "##non_optional_default_false=boolean false" ) ); std::unique_ptr< QgsProcessingParameterBoolean > fromCode( dynamic_cast< QgsProcessingParameterBoolean * >( QgsProcessingParameters::parameterFromScriptCode( code ) ) ); @@ -2861,6 +3047,36 @@ void TestQgsProcessing::parameterCrs() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QgsCoordinateReferenceSystem( "EPSG:3111" ), context ), QVariant( QStringLiteral( "EPSG:3111" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsCoordinateReferenceSystem(), context ), QVariant( QString() ) ); + QCOMPARE( def->valueAsJsonObject( "EPSG:12003", context ), QVariant( QStringLiteral( "EPSG:12003" ) ) ); + QCOMPARE( def->valueAsJsonObject( "ProjectCrs", context ), QVariant( QStringLiteral( "ProjectCrs" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + QCOMPARE( def->valueAsJsonObject( raster1, context ), QVariant( QString( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ) ); + QCOMPARE( def->valueAsJsonObject( r1->id(), context ), QVariant( QString( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsCoordinateReferenceSystem( "EPSG:3111" ), context, ok ), QStringLiteral( "EPSG:3111" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsCoordinateReferenceSystem(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "EPSG:12003", context, ok ), QStringLiteral( "EPSG:12003" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "ProjectCrs", context, ok ), QStringLiteral( "ProjectCrs" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( raster1, context, ok ), QString( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( r1->id(), context, ok ), QString( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterCrs fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -2985,6 +3201,24 @@ void TestQgsProcessing::parameterMapLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( raster1, context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( r1->id(), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( r1 ), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( raster1, context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( r1->id(), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( r1 ), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMapLayer('non_optional', '', defaultValue='')" ) ); @@ -3373,6 +3607,42 @@ void TestQgsProcessing::parameterExtent() QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QCOMPARE( def->valueAsPythonString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QStringLiteral( "QgsGeometry.fromWkt('LineString (10 10, 20 20)')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "1,2,3,4", context ), QVariant( QStringLiteral( "1,2,3,4" ) ) ); + QCOMPARE( def->valueAsJsonObject( r1->id(), context ), QVariant( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( r1 ), context ), QVariant( testDataDir + QStringLiteral( "landsat_4326.tif" ) ) ); + QCOMPARE( def->valueAsJsonObject( raster2, context ), QVariant( testDataDir + QStringLiteral( "landsat.tif" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsRectangle( 11, 12, 13, 14 ), context ), QVariant( QStringLiteral( "11, 13, 12, 14" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QVariant( QStringLiteral( "11, 13, 12, 14 [EPSG:4326]" ) ) ); + QCOMPARE( def->valueAsJsonObject( "1,2,3,4 [EPSG:4326]", context ), QVariant( QStringLiteral( "1,2,3,4 [EPSG:4326]" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QVariant( QStringLiteral( "LineString (10 10, 20 20)" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "1,2,3,4", context, ok ), QStringLiteral( "1,2,3,4" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( r1->id(), context, ok ), testDataDir + QStringLiteral( "landsat_4326.tif" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( r1 ), context, ok ), testDataDir + QStringLiteral( "landsat_4326.tif" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( raster2, context, ok ), testDataDir + QStringLiteral( "landsat.tif" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsRectangle( 11, 12, 13, 14 ), context, ok ), QStringLiteral( "11, 13, 12, 14" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsReferencedRectangle( QgsRectangle( 11, 12, 13, 14 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context, ok ), QStringLiteral( "11, 13, 12, 14 [EPSG:4326]" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "1,2,3,4 [EPSG:4326]", context, ok ), QStringLiteral( "1,2,3,4 [EPSG:4326]" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context, ok ), QStringLiteral( "LineString (10 10, 20 20)" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterExtent('non_optional', '', defaultValue='1,2,3,4')" ) ); @@ -3559,6 +3829,27 @@ void TestQgsProcessing::parameterPoint() QCOMPARE( def->valueAsPythonString( QgsReferencedPointXY( QgsPointXY( 11, 12 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QStringLiteral( "'11,12 [EPSG:4326]'" ) ); QCOMPARE( def->valueAsPythonString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QStringLiteral( "QgsGeometry.fromWkt('LineString (10 10, 20 20)')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "1,2", context ), QVariant( QStringLiteral( "1,2" ) ) ); + QCOMPARE( def->valueAsJsonObject( "1,2 [EPSG:4326]", context ), QVariant( QStringLiteral( "1,2 [EPSG:4326]" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsPointXY( 11, 12 ), context ), QVariant( QStringLiteral( "11,12" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsReferencedPointXY( QgsPointXY( 11, 12 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context ), QVariant( QStringLiteral( "11,12 [EPSG:4326]" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QVariant( QStringLiteral( "LineString (10 10, 20 20)" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "1,2", context, ok ), QStringLiteral( "1,2" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "1,2 [EPSG:4326]", context, ok ), QStringLiteral( "1,2 [EPSG:4326]" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsPointXY( 11, 12 ), context, ok ), QStringLiteral( "11,12" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsReferencedPointXY( QgsPointXY( 11, 12 ), QgsCoordinateReferenceSystem( "epsg:4326" ) ), context, ok ), QStringLiteral( "11,12 [EPSG:4326]" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context, ok ), QStringLiteral( "LineString (10 10, 20 20)" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterPoint('non_optional', '', defaultValue='1,2')" ) ); @@ -3730,6 +4021,25 @@ void TestQgsProcessing::parameterGeometry() QgsCoordinateReferenceSystem( "EPSG:4326" ) ), context ), QStringLiteral( "'CRS=EPSG:4326;LineString (10 10, 20 20)'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "LineString( 10 10, 20 20)", context ), QVariant( QStringLiteral( "LineString( 10 10, 20 20)" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context ), QVariant( QStringLiteral( "LineString (10 10, 20 20)" ) ) ); + QCOMPARE( def->valueAsJsonObject( QgsReferencedGeometry( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), + QgsCoordinateReferenceSystem( "EPSG:4326" ) ), context ), + QVariant( QStringLiteral( "CRS=EPSG:4326;LineString (10 10, 20 20)" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "LineString( 10 10, 20 20)", context, ok ), QStringLiteral( "LineString( 10 10, 20 20)" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), context, ok ), QStringLiteral( "LineString (10 10, 20 20)" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QgsReferencedGeometry( QgsGeometry::fromWkt( QStringLiteral( "LineString( 10 10, 20 20)" ) ), + QgsCoordinateReferenceSystem( "EPSG:4326" ) ), context, ok ), + QStringLiteral( "CRS=EPSG:4326;LineString (10 10, 20 20)" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterGeometry('non_optional', '', defaultValue='Point(1 2)')" ) ); @@ -3873,6 +4183,21 @@ void TestQgsProcessing::parameterFile() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "bricks.bmp", context ), QVariant( QStringLiteral( "bricks.bmp" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "bricks.bmp", context, ok ), QStringLiteral( "bricks.bmp" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterFile('non_optional', '', behavior=QgsProcessingParameterFile.File, extension='.bmp', defaultValue='abc.bmp')" ) ); @@ -3913,6 +4238,21 @@ void TestQgsProcessing::parameterFile() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "bricks.png", context ), QVariant( QStringLiteral( "bricks.png" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "bricks.png", context, ok ), QStringLiteral( "bricks.png" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterFile('non_optional', '', behavior=QgsProcessingParameterFile.File, fileFilter='PNG Files (*.png *.PNG)', defaultValue='abc.bmp')" ) ); @@ -4035,6 +4375,44 @@ void TestQgsProcessing::parameterMatrix() QCOMPARE( def->valueAsPythonString( "1,2,3", context ), QStringLiteral( "[1,2,3]" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << 1 << 2.5 << 3, context ), QVariant( QVariantList( { 1, 2.5, 3} ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << ( QVariantList() << 1 << 2 << 3 ) << ( QVariantList() << 1 << 2 << 3 ), context ), QVariant( QVariantList( {1, 2, 3, 1, 2, 3} ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << ( QVariantList() << 1 << QStringLiteral( "value" ) << 3 ) << ( QVariantList() << 1 << 2 << QStringLiteral( "it's a value" ) ), context ), QVariant( QVariantList( {1, "value", 3, 1, 2, "it's a value"} ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << ( QVariantList() << 1 << QVariant() << 3 ) << ( QVariantList() << QVariant() << 2 << 3 ), context ), QVariant( QVariantList( {1, QVariant(), 3, QVariant(), 2, 3} ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << ( QVariantList() << 1 << QString( "" ) << 3 ) << ( QVariantList() << 1 << 2 << QString( "" ) ), context ), QVariant( QVariantList( {1, QString(), 3, 1, 2, QString()} ) ) ); + QCOMPARE( def->valueAsJsonObject( "1,2,3", context ), QVariant( QStringLiteral( "1,2,3" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariantList() << 1 << 2.5 << 3, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << ( QVariantList() << 1 << 2 << 3 ) << ( QVariantList() << 1 << 2 << 3 ), context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << ( QVariantList() << 1 << QStringLiteral( "value" ) << 3 ) << ( QVariantList() << 1 << 2 << QStringLiteral( "it's a value" ) ), context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << ( QVariantList() << 1 << QVariant() << 3 ) << ( QVariantList() << QVariant() << 2 << 3 ), context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << ( QVariantList() << 1 << QString( "" ) << 3 ) << ( QVariantList() << 1 << 2 << QString( "" ) ), context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( "1,2,3", context, ok ), QVariant( QStringLiteral( "1,2,3" ) ) ); + QVERIFY( ok ); + + QCOMPARE( def->valueAsStringList( QVariantList() << 1 << 2.5 << 3, context, ok ), QStringList( {QStringLiteral( "1" ), QStringLiteral( "2.5" ), QStringLiteral( "3" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << ( QVariantList() << 1 << 2 << 3 ) << ( QVariantList() << 1 << 2 << 3 ), context, ok ), QStringList( {QStringLiteral( "1" ), QStringLiteral( "2" ), QStringLiteral( "3" ), QStringLiteral( "1" ), QStringLiteral( "2" ), QStringLiteral( "3" )} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << ( QVariantList() << 1 << QStringLiteral( "value" ) << 3 ) << ( QVariantList() << 1 << 2 << QStringLiteral( "it's a value" ) ), context, ok ), QStringList( {"1", "value", "3", "1", "2", "it's a value" } ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << ( QVariantList() << 1 << QVariant() << 3 ) << ( QVariantList() << QVariant() << 2 << 3 ), context, ok ), QStringList( {"1", "3", "2", "3"} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << ( QVariantList() << 1 << QString( "" ) << 3 ) << ( QVariantList() << 1 << 2 << QString( "" ) ), context, ok ), QStringList( {"1", "", "3", "1", "2", "" } ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMatrix('non_optional', '', numberRows=3, hasFixedNumberRows=False, headers=[], defaultValue=None)" ) ); @@ -4219,6 +4597,30 @@ void TestQgsProcessing::parameterLayerList() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "layer12312312", context ), QVariant( QStringLiteral( "layer12312312" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( r1 ), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( r1->id(), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringList() << r1->id() << raster2, context ), QVariant( QVariantList( { QString( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ), QString( testDataDir + QStringLiteral( "landsat.tif" ) ) } ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "layer12312312", context, ok ), QStringLiteral( "layer12312312" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( r1 ), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( r1->id(), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringList() << r1->id() << raster2, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + + QCOMPARE( def->valueAsStringList( QStringList() << r1->id() << raster2, context, ok ), QStringList( { QString( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ), QString( testDataDir + QStringLiteral( "landsat.tif" ) ) } ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMultipleLayers('non_optional', '', layerType=QgsProcessing.TypeMapLayer, defaultValue='')" ) ); @@ -4410,6 +4812,26 @@ void TestQgsProcessing::parameterLayerList() QCOMPARE( def->valueAsPythonString( "layer12312312", context ), QStringLiteral( "'layer12312312'" ) ); QCOMPARE( def->valueAsPythonString( QStringList() << "a" << "B", context ), QStringLiteral( "['a','B']" ) ); QCOMPARE( def->valueAsPythonString( QVariantList() << "c" << "d", context ), QStringLiteral( "['c','d']" ) ); + + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "layer12312312", context ), QVariant( QStringLiteral( "layer12312312" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringList() << "a" << "B", context ), QVariant( QVariantList( { QStringLiteral( "a" ), QStringLiteral( "B" ) } ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << "c" << "d", context ), QVariant( QVariantList( { QStringLiteral( "c" ), QStringLiteral( "d" ) } ) ) ); + + ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "layer12312312", context, ok ), QStringLiteral( "layer12312312" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringList() << "a" << "B", context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << "c" << "d", context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( QStringList() << "a" << "B", context, ok ), QStringList( {"a", "B"} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << "c" << "d", context, ok ), QStringList( {"c", "d"} ) ); + QVERIFY( ok ); } void TestQgsProcessing::parameterDistance() @@ -4473,6 +4895,18 @@ void TestQgsProcessing::parameterDistance() QCOMPARE( def->valueAsPythonString( QStringLiteral( "1.1" ), context ), QStringLiteral( "1.1" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1.1" ), context ), QVariant( QStringLiteral( "1.1" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1.1" ), context, ok ), QStringLiteral( "1.1" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterDistance fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -4573,6 +5007,18 @@ void TestQgsProcessing::parameterDuration() QCOMPARE( def->valueAsPythonString( QStringLiteral( "1.1" ), context ), QStringLiteral( "1.1" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1.1" ), context ), QVariant( QStringLiteral( "1.1" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1.1" ), context, ok ), QStringLiteral( "1.1" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterDuration fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -4664,6 +5110,18 @@ void TestQgsProcessing::parameterScale() QCOMPARE( def->valueAsPythonString( QStringLiteral( "1.1" ), context ), QStringLiteral( "1.1" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( "5" ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1.1" ), context ), QVariant( QStringLiteral( "1.1" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1.1" ), context, ok ), QStringLiteral( "1.1" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterScale fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -4771,6 +5229,18 @@ void TestQgsProcessing::parameterNumber() QCOMPARE( def->valueAsPythonString( QStringLiteral( "1.1" ), context ), QStringLiteral( "1.1" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( "5" ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1.1" ), context ), QVariant( QStringLiteral( "1.1" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1.1" ), context, ok ), QStringLiteral( "1.1" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterNumber('non_optional', '', type=QgsProcessingParameterNumber.Double, minValue=11, maxValue=21, defaultValue=5)" ) ); @@ -4896,6 +5366,21 @@ void TestQgsProcessing::parameterRange() QCOMPARE( def->valueAsPythonString( QVariantList() << 1.1 << 2, context ), QStringLiteral( "[1.1,2]" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( "1.1,2", context ), QVariant( QStringLiteral( "1.1,2" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << 1.1 << 2, context ), QVariant( QVariantList( { QVariant( 1.1 ), QVariant( 2 )} ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "1.1,2", context, ok ), QStringLiteral( "1.1,2" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariantList() << 1.1 << 2, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( QVariantList() << 1.1 << 2, context, ok ), QStringList( {"1.1", "2"} ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterRange('non_optional', '', type=QgsProcessingParameterNumber.Double, defaultValue=[5,6])" ) ); @@ -5062,6 +5547,24 @@ void TestQgsProcessing::parameterRasterLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( raster1, context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( r1->id(), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( r1 ), context ), QVariant( testDataDir + QStringLiteral( "tenbytenraster.asc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( raster1, context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( r1->id(), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( r1 ), context, ok ), testDataDir + QStringLiteral( "tenbytenraster.asc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterRasterLayer('non_optional', '', defaultValue=None)" ) ); @@ -5179,6 +5682,18 @@ void TestQgsProcessing::parameterEnum() QCOMPARE( def->valueAsPythonString( QStringLiteral( "1.1" ), context ), QStringLiteral( "1" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1.1" ), context ), QVariant( QStringLiteral( "1.1" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1.1" ), context, ok ), QStringLiteral( "1.1" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterEnum('non_optional', '', options=['A','B','C'], allowMultiple=False, usesStaticStrings=False, defaultValue=2)" ) ); @@ -5242,6 +5757,20 @@ void TestQgsProcessing::parameterEnum() QCOMPARE( def->valueAsPythonString( QVariantList() << 1 << 2, context ), QStringLiteral( "[1,2]" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "1,2" ), context ), QStringLiteral( "[1,2]" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << 1 << 2, context ), QVariant( QVariantList( {1, 2} ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "1,2" ), context ), QVariant( QStringLiteral( "1,2" ) ) ); + + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariantList() << 1 << 2, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "1,2" ), context, ok ), QStringLiteral( "1,2" ) ); + QVERIFY( ok ); + + QCOMPARE( def->valueAsStringList( QVariantList() << 1 << 2, context, ok ), QStringList( {"1", "2"} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsPythonComment( QVariant(), context ), QString() ); QCOMPARE( def->valueAsPythonComment( 2, context ), QStringLiteral( "C" ) ); QCOMPARE( def->valueAsPythonComment( QVariantList() << 1 << 2, context ), QStringLiteral( "B,C" ) ); @@ -5498,6 +6027,27 @@ void TestQgsProcessing::parameterString() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterString('non_optional', '', multiLine=False, defaultValue=None)" ) ); @@ -5652,6 +6202,27 @@ void TestQgsProcessing::parameterAuthConfig() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterAuthConfig('non_optional', '', defaultValue='')" ) ); @@ -5767,6 +6338,21 @@ void TestQgsProcessing::parameterExpression() QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc\ndef" ), context ), QStringLiteral( "'abc\\ndef'" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterExpression('non_optional', '', parentLayerParameterName='', defaultValue='1+1')" ) ); @@ -5855,6 +6441,20 @@ void TestQgsProcessing::parameterField() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "probably\'invalid\"field", context ), QStringLiteral( "'probably\\'invalid\"field'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "probably\'invalid\"field", context ), QVariant( QStringLiteral( "probably\'invalid\"field" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "probably\'invalid\"field" ), context, ok ), QStringLiteral( "probably\'invalid\"field" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterField('non_optional', '', type=QgsProcessingParameterField.Any, parentLayerParameterName='', allowMultiple=False, defaultValue=None)" ) ); @@ -5955,7 +6555,17 @@ void TestQgsProcessing::parameterField() QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) ); QCOMPARE( def->valueAsPythonString( QStringList() << "a" << "b", context ), QStringLiteral( "['a','b']" ) ); - QCOMPARE( def->valueAsPythonString( QStringList() << "a" << "b", context ), QStringLiteral( "['a','b']" ) ); + + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringList() << "a" << "b", context ), QVariant( QVariantList( {QStringLiteral( "a" ), QStringLiteral( "b" ) } ) ) ); + + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringList() << "a" << "b", context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( QStringList() << "a" << "b", context, ok ), QStringList( {"a", "b"} ) ); + QVERIFY( ok ); QVariantMap map = def->toVariantMap(); QgsProcessingParameterField fromMap( "x" ); @@ -6150,6 +6760,24 @@ void TestQgsProcessing::parameterVectorLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( vector1, context ), QVariant( testDataDir + QStringLiteral( "multipoint.shp" ) ) ); + QCOMPARE( def->valueAsJsonObject( v1->id(), context ), QVariant( testDataDir + QStringLiteral( "multipoint.shp" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( v1 ), context ), QVariant( testDataDir + QStringLiteral( "multipoint.shp" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( vector1, context, ok ), testDataDir + QStringLiteral( "multipoint.shp" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( v1->id(), context, ok ), testDataDir + QStringLiteral( "multipoint.shp" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( v1 ), context, ok ), testDataDir + QStringLiteral( "multipoint.shp" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterVectorLayer('non_optional', '', defaultValue='somelayer')" ) ); @@ -6279,6 +6907,24 @@ void TestQgsProcessing::parameterMeshLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.2dm" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.2dm'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( mesh, context ), QVariant( testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ) ); + QCOMPARE( def->valueAsJsonObject( m1->id(), context ), QVariant( testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( m1 ), context ), QVariant( testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.2dm" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.2dm" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( mesh, context, ok ), testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( m1->id(), context, ok ), testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( m1 ), context, ok ), testDataDir + QStringLiteral( "mesh/quad_and_triangle.2dm" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.2dm" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.2dm" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMeshLayer('non_optional', '', defaultValue='somelayer')" ) ); @@ -6426,6 +7072,62 @@ void TestQgsProcessing::parameterFeatureSource() QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "postgres://uri='complex' username=\"complex\"" ), context ), QStringLiteral( "'postgres://uri=\\'complex\\' username=\"complex\"'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QVariant( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( "abc'def" ) ), context ), QVariant( QStringLiteral( "abc'def" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( v2->id() ) ), context ), QVariant( vector2 ) ); + QCOMPARE( def->valueAsJsonObject( v2->id(), context ), QVariant( vector2 ) ); + // currently limits, flags, etc from feature source definitions cannot be serialized to JSON... + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), true ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "dbname='mydb' host=localhost port=5432 sslmode=disable key='id'" ), true ) ), context ), QVariant( QStringLiteral( "dbname='mydb' host=localhost port=5432 sslmode=disable key='id'" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, 11 ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1 ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck, QgsFeatureRequest::GeometrySkipInvalid ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature, QgsFeatureRequest::GeometrySkipInvalid ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck | QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature, QgsFeatureRequest::GeometrySkipInvalid ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( v2 ), context ), QVariant( vector2 ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "postgres://uri='complex' username=\"complex\"" ), context ), QVariant( QStringLiteral( "postgres://uri='complex' username=\"complex\"" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( "abc'def" ) ), context, ok ), QStringLiteral( "abc'def" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( v2->id() ) ), context, ok ), vector2 ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( v2->id(), context, ok ), vector2 ); + QVERIFY( ok ); + // currently limits, flags, etc from feature source definitions cannot be serialized to string + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), true ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "dbname='mydb' host=localhost port=5432 sslmode=disable key='id'" ), true ) ), context, ok ), QStringLiteral( "dbname='mydb' host=localhost port=5432 sslmode=disable key='id'" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, 11 ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1 ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck, QgsFeatureRequest::GeometrySkipInvalid ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature, QgsFeatureRequest::GeometrySkipInvalid ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingFeatureSourceDefinition( QgsProperty::fromValue( "abc" ), false, -1, QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck | QgsProcessingFeatureSourceDefinition::Flag::FlagCreateIndividualOutputPerInputFeature, QgsFeatureRequest::GeometrySkipInvalid ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( v2 ), context, ok ), vector2 ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "postgres://uri='complex' username=\"complex\"" ), context, ok ), QStringLiteral( "postgres://uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterFeatureSource fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -6554,6 +7256,27 @@ void TestQgsProcessing::parameterFeatureSink() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QCOMPARE( def->defaultFileExtension(), QStringLiteral( "gpkg" ) ); QCOMPARE( def->generateTemporaryDestination(), QStringLiteral( "memory:" ) ); def->setSupportsNonFileBasedOutput( false ); @@ -6725,6 +7448,27 @@ void TestQgsProcessing::parameterVectorOut() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QCOMPARE( def->defaultFileExtension(), QStringLiteral( "gpkg" ) ); QVERIFY( def->generateTemporaryDestination().endsWith( QLatin1String( ".gpkg" ) ) ); QVERIFY( def->generateTemporaryDestination().startsWith( QgsProcessingUtils::tempFolder() ) ); @@ -6913,6 +7657,7 @@ void TestQgsProcessing::parameterRasterOut() QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.tif", &context ) ); QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); QCOMPARE( def->defaultFileExtension(), QStringLiteral( "tif" ) ); QVERIFY( def->generateTemporaryDestination().endsWith( QLatin1String( ".tif" ) ) ); QVERIFY( def->generateTemporaryDestination().startsWith( QgsProcessingUtils::tempFolder() ) ); @@ -6936,6 +7681,24 @@ void TestQgsProcessing::parameterRasterOut() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterRasterDestination fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -7047,6 +7810,10 @@ void TestQgsProcessing::parameterPointCloudOut() QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.las", &context ) ); QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); QCOMPARE( def->defaultFileExtension(), QStringLiteral( "las" ) ); QVERIFY( def->generateTemporaryDestination().endsWith( QLatin1String( ".las" ) ) ); QVERIFY( def->generateTemporaryDestination().startsWith( QgsProcessingUtils::tempFolder() ) ); @@ -7070,6 +7837,23 @@ void TestQgsProcessing::parameterPointCloudOut() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterPointCloudDestination fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -7223,6 +8007,27 @@ void TestQgsProcessing::parameterFileOut() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterFileDestination fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -7323,6 +8128,21 @@ void TestQgsProcessing::parameterFolderOut() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\" ), context, ok ), QStringLiteral( "c:\\test\\new data\\" ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterFolderDestination fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -7394,6 +8214,15 @@ void TestQgsProcessing::parameterBand() QCOMPARE( def->valueAsPythonString( QVariant(), context ), QStringLiteral( "None" ) ); QCOMPARE( def->valueAsPythonString( 5, context ), QStringLiteral( "5" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterBand('non_optional', '', parentLayerParameterName='', allowMultiple=False, defaultValue=None)" ) ); QString code = def->asScriptCode(); @@ -7441,6 +8270,22 @@ void TestQgsProcessing::parameterBand() QCOMPARE( def->valueAsPythonString( QStringList() << "1" << "2", context ), QStringLiteral( "[1,2]" ) ); QCOMPARE( def->valueAsPythonString( QVariantList() << 1 << 2, context ), QStringLiteral( "[1,2]" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringList() << "1" << "2", context ), QVariant( QVariantList( { "1", "2" } ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariantList() << 1 << 2, context ), QVariant( QVariantList( { 1, 2} ) ) ); + + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringList() << "1" << "2", context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( def->valueAsString( QVariantList() << 1 << 2, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( QStringList() << "1" << "2", context, ok ), QStringList( {"1", "2"} ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsStringList( QVariantList() << 1 << 2, context, ok ), QStringList( {"1", "2"} ) ); + QVERIFY( ok ); + const QVariantMap map = def->toVariantMap(); QgsProcessingParameterBand fromMap( "x" ); QVERIFY( fromMap.fromVariantMap( map ) ); @@ -7534,6 +8379,27 @@ void TestQgsProcessing::parameterLayout() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterLayout('non_optional', '', defaultValue=None)" ) ); @@ -7686,6 +8552,18 @@ void TestQgsProcessing::parameterLayoutItem() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "probably\'invalid\"item", context ), QStringLiteral( "'probably\\'invalid\"item'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "probably\'invalid\"item", context ), QVariant( QStringLiteral( "probably\'invalid\"item" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "probably\'invalid\"item", context, ok ), QStringLiteral( "probably\'invalid\"item" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterLayoutItem('non_optional', '', parentLayoutParameterName='', defaultValue=None)" ) ); @@ -7812,6 +8690,24 @@ void TestQgsProcessing::parameterColor() QCOMPARE( def->valueAsPythonString( QColor( 255, 0, 0 ), context ), QStringLiteral( "QColor(255, 0, 0)" ) ); QCOMPARE( def->valueAsPythonString( QColor( 255, 0, 0, 100 ), context ), QStringLiteral( "QColor(255, 0, 0, 100)" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "#ff0000" ), context ), QVariant( QStringLiteral( "#ff0000" ) ) ); + QCOMPARE( def->valueAsJsonObject( QColor(), context ), QVariant( QString() ) ); + QCOMPARE( def->valueAsJsonObject( QColor( 255, 0, 0 ), context ), QVariant( QStringLiteral( "rgba( 255, 0, 0, 1.00 )" ) ) ); + QCOMPARE( def->valueAsJsonObject( QColor( 255, 0, 0, 100 ), context ), QVariant( QStringLiteral( "rgba( 255, 0, 0, 0.39 )" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "#ff0000" ), context, ok ), QStringLiteral( "#ff0000" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QColor(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QColor( 255, 0, 0 ), context, ok ), QStringLiteral( "rgba( 255, 0, 0, 1.00 )" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QColor( 255, 0, 0, 100 ), context, ok ), QStringLiteral( "rgba( 255, 0, 0, 0.39 )" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterColor('non_optional', '', opacityEnabled=True, defaultValue=None)" ) ); @@ -7959,6 +8855,25 @@ void TestQgsProcessing::parameterCoordinateOperation() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterCoordinateOperation('non_optional', '', sourceCrsParameterName='src', destinationCrsParameterName='dest', staticSourceCrs=QgsCoordinateReferenceSystem('EPSG:7855'), staticDestinationCrs=QgsCoordinateReferenceSystem('EPSG:28355'), defaultValue=None)" ) ); @@ -8080,6 +8995,25 @@ void TestQgsProcessing::parameterMapTheme() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMapTheme('non_optional', '', defaultValue=None)" ) ); @@ -8200,6 +9134,25 @@ void TestQgsProcessing::parameterProviderConnection() QCOMPARE( def->valueAsPythonString( "uri='complex' username=\"complex\"", context ), QStringLiteral( "'uri=\\'complex\\' username=\"complex\"'" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.dat'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), QVariant( 5 ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QVariant( QStringLiteral( "abc\ndef" ) ) ); + QCOMPARE( def->valueAsJsonObject( "uri='complex' username=\"complex\"", context ), QVariant( QStringLiteral( "uri='complex' username=\"complex\"" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.dat" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.dat" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "uri='complex' username=\"complex\"", context, ok ), QStringLiteral( "uri='complex' username=\"complex\"" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.dat" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.dat" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterProviderConnection('non_optional', '', 'postgres', defaultValue=None)" ) ); @@ -8322,6 +9275,18 @@ void TestQgsProcessing::parameterDatabaseSchema() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "probably\'invalid\"schema", context ), QStringLiteral( "'probably\\'invalid\"schema'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "probably\'invalid\"schema", context ), QVariant( QStringLiteral( "probably\'invalid\"schema" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "probably\'invalid\"schema", context, ok ), QStringLiteral( "probably\'invalid\"schema" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDatabaseSchema('non_optional', '', connectionParameterName='', defaultValue=None)" ) ); @@ -8400,6 +9365,18 @@ void TestQgsProcessing::parameterDatabaseTable() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( "probably\'invalid\"schema", context ), QStringLiteral( "'probably\\'invalid\"schema'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QVariant( QStringLiteral( "abc" ) ) ); + QCOMPARE( def->valueAsJsonObject( "probably\'invalid\"schema", context ), QVariant( QStringLiteral( "probably\'invalid\"schema" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( "probably\'invalid\"schema", context, ok ), QStringLiteral( "probably\'invalid\"schema" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDatabaseTable('non_optional', '', connectionParameterName='', schemaParameterName='', defaultValue=None)" ) ); @@ -8577,6 +9554,27 @@ void TestQgsProcessing::parameterAggregate() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QVariant( QVariantList() << map << map2 ), context ), QStringLiteral( "[{'aggregate': 'e','input': 'i','name': 'n','type': 't'},{'aggregate': 'e2','input': 'i2','name': 'n2','type': 't2'}]" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( 5, context ), 5 ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc" ), context ), QStringLiteral( "abc" ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "abc\ndef" ), context ), QStringLiteral( "abc\ndef" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant( QVariantList() << map << map2 ), context ), QVariant( QVariantList() << map << map2 ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( 5, context, ok ), QStringLiteral( "5" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc" ), context, ok ), QStringLiteral( "abc" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "abc\ndef" ), context, ok ), QStringLiteral( "abc\ndef" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant( QVariantList() << map << map2 ), context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( QVariant( QVariantList() << map << map2 ), context, ok ), QStringList() ); + QVERIFY( !ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterAggregate('non_optional', '', parentLayerParameterName='parent')" ) ); @@ -8647,6 +9645,16 @@ void TestQgsProcessing::parameterTinInputLayers() const QString valueAsPythonString = def->valueAsPythonString( layerList, context ); QCOMPARE( valueAsPythonString, QStringLiteral( "[{'source': 'PointLayerForTin','type': 0,'attributeIndex': -1}]" ) ); + QCOMPARE( QString::fromStdString( QgsJsonUtils::jsonFromVariant( def->valueAsJsonObject( layerList, context ) ).dump() ), + QStringLiteral( "[{\"attributeIndex\":-1,\"source\":\"%1\",\"type\":0}]" ).arg( vectorLayer->source() ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( layerList, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( layerList, context, ok ), QStringList() ); + QVERIFY( !ok ); + const QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterTinInputLayers('tin input layer', '')" ) ); } @@ -8694,6 +9702,15 @@ void TestQgsProcessing::parameterMeshDatasetGroups() QCOMPARE( valueAsPythonString, QStringLiteral( "[0,5]" ) ); QCOMPARE( QgsProcessingParameterMeshDatasetGroups::valueAsDatasetGroup( groupsList ), QList() << 0 << 5 ); + QCOMPARE( def->valueAsJsonObject( groupsList, context ), QVariant( QVariantList( {0, 5 } ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( groupsList, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( groupsList, context, ok ), QStringList( {"0", "5"} ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterMeshDatasetGroups('dataset groups', 'groups', dataType=[QgsMeshDatasetGroupMetadata.DataOnVertices])" ) ); @@ -8724,6 +9741,14 @@ void TestQgsProcessing::parameterMeshDatasetGroups() QCOMPARE( valueAsPythonString, QStringLiteral( "[2,6]" ) ); QCOMPARE( QgsProcessingParameterMeshDatasetGroups::valueAsDatasetGroup( groupsList ), QList() << 2 << 6 ); + QCOMPARE( def->valueAsJsonObject( groupsList, context ), QVariant( QVariantList( {2, 6 } ) ) ); + + QCOMPARE( def->valueAsString( groupsList, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( groupsList, context, ok ), QStringList( {"2", "6"} ) ); + QVERIFY( ok ); + QVERIFY( !def->dependsOnOtherParameters().isEmpty() ); QCOMPARE( def->meshLayerParameterName(), QStringLiteral( "layer parameter" ) ); @@ -8757,6 +9782,12 @@ void TestQgsProcessing::parameterMeshDatasetTime() QCOMPARE( def->valueAsPythonString( QDateTime( QDate( 2020, 01, 01 ), QTime( 10, 0, 0 ) ), context ), QStringLiteral( "{'type': 'defined-date-time','value': QDateTime(QDate(2020, 1, 1), QTime(10, 0, 0))}" ) ); + QCOMPARE( def->valueAsJsonObject( QDateTime( QDate( 2020, 01, 01 ), QTime( 10, 0, 0 ) ), context ), QVariant( QStringLiteral( "2020-01-01T10:00:00" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QDateTime( QDate( 2020, 01, 01 ), QTime( 10, 0, 0 ) ), context, ok ), QStringLiteral( "2020-01-01T10:00:00" ) ); + QVERIFY( ok ); + QVariantMap value; QVERIFY( !def->checkValueIsAcceptable( value ) ); value[QStringLiteral( "test" )] = QStringLiteral( "test" ); @@ -8769,11 +9800,24 @@ void TestQgsProcessing::parameterMeshDatasetTime() value[QStringLiteral( "type" )] = QStringLiteral( "static" ); QVERIFY( def->checkValueIsAcceptable( value ) ); QCOMPARE( def->valueAsPythonString( value, context ), QStringLiteral( "{'type': 'static'}" ) ); + + QCOMPARE( def->valueAsString( value, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( value, context, ok ), QStringList() ); + QVERIFY( !ok ); + QCOMPARE( QgsProcessingParameterMeshDatasetTime::valueAsTimeType( value ), QStringLiteral( "static" ) ); value[QStringLiteral( "type" )] = QStringLiteral( "current-context-time" ); QVERIFY( def->checkValueIsAcceptable( value ) ); QCOMPARE( def->valueAsPythonString( value, context ), QStringLiteral( "{'type': 'current-context-time'}" ) ); + QCOMPARE( QString::fromStdString( QgsJsonUtils::jsonFromVariant( def->valueAsJsonObject( value, context ) ).dump() ), + QStringLiteral( "{\"type\":\"current-context-time\"}" ) ); + + QCOMPARE( def->valueAsString( value, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( QgsProcessingParameterMeshDatasetTime::valueAsTimeType( value ), QStringLiteral( "current-context-time" ) ); value[QStringLiteral( "type" )] = QStringLiteral( "defined-date-time" ); @@ -8781,6 +9825,12 @@ void TestQgsProcessing::parameterMeshDatasetTime() value[QStringLiteral( "value" )] = QDateTime( QDate( 2123, 1, 2 ), QTime( 1, 2, 3 ) ); QVERIFY( def->checkValueIsAcceptable( value ) ); QCOMPARE( def->valueAsPythonString( value, context ), QStringLiteral( "{'type': 'defined-date-time','value': QDateTime(QDate(2123, 1, 2), QTime(1, 2, 3))}" ) ); + QCOMPARE( QString::fromStdString( QgsJsonUtils::jsonFromVariant( def->valueAsJsonObject( value, context ) ).dump() ), + QStringLiteral( "{\"type\":\"defined-date-time\",\"value\":\"2123-01-02T01:02:03\"}" ) ); + + QCOMPARE( def->valueAsString( value, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( QgsProcessingParameterMeshDatasetTime::valueAsTimeType( value ), QStringLiteral( "defined-date-time" ) ); QCOMPARE( QgsProcessingParameterMeshDatasetTime::timeValueAsDefinedDateTime( value ), QDateTime( QDate( 2123, 1, 2 ), QTime( 1, 2, 3 ) ) ); QVERIFY( !QgsProcessingParameterMeshDatasetTime::timeValueAsDatasetIndex( value ).isValid() ); @@ -8791,6 +9841,12 @@ void TestQgsProcessing::parameterMeshDatasetTime() value[QStringLiteral( "value" )] = QVariantList() << 1 << 5; QVERIFY( def->checkValueIsAcceptable( value ) ); QCOMPARE( def->valueAsPythonString( value, context ), QStringLiteral( "{'type': 'dataset-time-step','value': [1,5]}" ) ); + QCOMPARE( QString::fromStdString( QgsJsonUtils::jsonFromVariant( def->valueAsJsonObject( value, context ) ).dump() ), + QStringLiteral( "{\"type\":\"dataset-time-step\",\"value\":[1,5]}" ) ); + + QCOMPARE( def->valueAsString( value, context, ok ), QString() ); + QVERIFY( !ok ); + QCOMPARE( QgsProcessingParameterMeshDatasetTime::valueAsTimeType( value ), QStringLiteral( "dataset-time-step" ) ); QVERIFY( !QgsProcessingParameterMeshDatasetTime::timeValueAsDefinedDateTime( value ).isValid() ); QVERIFY( QgsProcessingParameterMeshDatasetTime::timeValueAsDatasetIndex( value ) == QgsMeshDatasetIndex( 1, 5 ) ); @@ -8874,6 +9930,21 @@ void TestQgsProcessing::parameterDateTime() QCOMPARE( def->valueAsPythonString( QStringLiteral( "2015-12-31" ), context ), QStringLiteral( "2015-12-31" ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QDateTime( QDate( 2014, 12, 31 ), QTime( 0, 0, 0 ) ), context ), QVariant( QStringLiteral( "2014-12-31T00:00:00" ) ) ); + QCOMPARE( def->valueAsJsonObject( QDateTime( QDate( 2014, 12, 31 ), QTime( 12, 11, 10 ) ), context ), QVariant( QStringLiteral( "2014-12-31T12:11:10" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "2015-12-31" ), context ), QVariant( QStringLiteral( "2015-12-31" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QDateTime( QDate( 2014, 12, 31 ), QTime( 0, 0, 0 ) ), context, ok ), QStringLiteral( "2014-12-31T00:00:00" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QDateTime( QDate( 2014, 12, 31 ), QTime( 12, 11, 10 ) ), context, ok ), QStringLiteral( "2014-12-31T12:11:10" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "2015-12-31" ), context, ok ), QStringLiteral( "2015-12-31" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDateTime('non_optional', '', type=QgsProcessingParameterDateTime.DateTime, minValue=QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0)), maxValue=QDateTime(QDate(2015, 12, 31), QTime(0, 0, 0)), defaultValue=QDateTime(QDate(2010, 4, 3), QTime(12, 11, 10)))" ) ); @@ -9008,6 +10079,9 @@ void TestQgsProcessing::parameterDateTime() QVERIFY( def->checkValueIsAcceptable( QStringLiteral( "2015-12-31" ) ) ); QCOMPARE( def->valueAsPythonString( QDate( 2014, 12, 31 ), context ), QStringLiteral( "QDate(2014, 12, 31)" ) ); + QCOMPARE( def->valueAsJsonObject( QDate( 2014, 12, 31 ), context ), QVariant( QStringLiteral( "2014-12-31" ) ) ); + QCOMPARE( def->valueAsString( QDate( 2014, 12, 31 ), context, ok ), QStringLiteral( "2014-12-31" ) ); + QVERIFY( ok ); pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDateTime('non_optional', '', type=QgsProcessingParameterDateTime.Date, minValue=QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0)), maxValue=QDateTime(QDate(2015, 12, 31), QTime(0, 0, 0)), defaultValue=QDate(2010, 4, 3))" ) ); @@ -9112,6 +10186,9 @@ void TestQgsProcessing::parameterDateTime() QVERIFY( def->checkValueIsAcceptable( QStringLiteral( "10:40:01" ) ) ); QCOMPARE( def->valueAsPythonString( QTime( 13, 14, 15 ), context ), QStringLiteral( "QTime(13, 14, 15)" ) ); + QCOMPARE( def->valueAsJsonObject( QTime( 13, 14, 15 ), context ), QVariant( QStringLiteral( "13:14:15" ) ) ); + QCOMPARE( def->valueAsString( QTime( 13, 14, 15 ), context, ok ), QStringLiteral( "13:14:15" ) ); + QVERIFY( ok ); pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDateTime('non_optional', '', type=QgsProcessingParameterDateTime.Time, minValue=QDateTime(QDate(1, 1, 1), QTime(10, 0, 0)), maxValue=QDateTime(QDate(1, 1, 1), QTime(11, 0, 0)), defaultValue=QTime(12, 11, 13))" ) ); @@ -9209,6 +10286,14 @@ void TestQgsProcessing::parameterDxfLayers() const QString valueAsPythonString = def->valueAsPythonString( layerList, context ); QCOMPARE( valueAsPythonString, QStringLiteral( "[{'layer': '%1','attributeIndex': -1}]" ).arg( vectorLayer->source() ) ); + QCOMPARE( QString::fromStdString( QgsJsonUtils::jsonFromVariant( def->valueAsJsonObject( layerList, context ) ).dump() ), + QStringLiteral( "[{\"attributeIndex\":-1,\"layer\":\"%1\"}]" ).arg( vectorLayer->source() ) ); + bool ok = false; + QCOMPARE( def->valueAsString( layerList, context, ok ), QString() ); + QVERIFY( !ok ); + + QCOMPARE( def->valueAsStringList( layerList, context, ok ), QStringList() ); + QVERIFY( !ok ); const QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterDxfLayers('dxf input layer', '')" ) ); @@ -9300,6 +10385,21 @@ void TestQgsProcessing::parameterAnnotationLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( al ), context ), QStringLiteral( "'%1'" ).arg( al->id() ) ); QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "main" ), context ), QVariant( QStringLiteral( "main" ) ) ); + QCOMPARE( def->valueAsJsonObject( al->id(), context ), QVariant( al->id() ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( al ), context ), QVariant( al->id() ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "main" ), context, ok ), QStringLiteral( "main" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( al->id(), context, ok ), al->id() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( al ), context, ok ), al->id() ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterAnnotationLayer('non_optional', '', defaultValue='somelayer')" ) ); @@ -9395,7 +10495,9 @@ void TestQgsProcessing::parameterPointCloudLayer() QVERIFY( !def->createFileFilter().contains( QStringLiteral( "*.shp" ) ) ); QVERIFY( !def->createFileFilter().contains( QStringLiteral( "*.tif" ) ) ); +#ifdef HAVE_PDAL QVERIFY( def->createFileFilter().contains( QStringLiteral( "*.las" ) ) ); +#endif QVERIFY( def->createFileFilter().contains( QStringLiteral( "*.*" ) ) ); // using existing map layer ID @@ -9430,6 +10532,24 @@ void TestQgsProcessing::parameterPointCloudLayer() QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) ); QCOMPARE( def->valueAsPythonString( QStringLiteral( "c:\\test\\new data\\test.las" ), context ), QStringLiteral( "'c:\\\\test\\\\new data\\\\test.las'" ) ); + QCOMPARE( def->valueAsJsonObject( QVariant(), context ), QVariant() ); + QCOMPARE( def->valueAsJsonObject( pointCloud, context ), QVariant( testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ) ); + QCOMPARE( def->valueAsJsonObject( pc1->id(), context ), QVariant( testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ) ); + QCOMPARE( def->valueAsJsonObject( QVariant::fromValue( pc1 ), context ), QVariant( testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ) ); + QCOMPARE( def->valueAsJsonObject( QStringLiteral( "c:\\test\\new data\\test.las" ), context ), QVariant( QStringLiteral( "c:\\test\\new data\\test.las" ) ) ); + + bool ok = false; + QCOMPARE( def->valueAsString( QVariant(), context, ok ), QString() ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( pointCloud, context, ok ), testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( pc1->id(), context, ok ), testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QVariant::fromValue( pc1 ), context, ok ), testDataDir + QStringLiteral( "point_clouds/ept/sunshine-coast/ept.json" ) ); + QVERIFY( ok ); + QCOMPARE( def->valueAsString( QStringLiteral( "c:\\test\\new data\\test.las" ), context, ok ), QStringLiteral( "c:\\test\\new data\\test.las" ) ); + QVERIFY( ok ); + QString pythonCode = def->asPythonString(); QCOMPARE( pythonCode, QStringLiteral( "QgsProcessingParameterPointCloudLayer('non_optional', '', defaultValue='somelayer')" ) ); @@ -9832,6 +10952,22 @@ void TestQgsProcessing::asPythonCommand() alg.runAsPythonCommandChecks(); } +void TestQgsProcessing::asQgisProcessCommand() +{ + // test converting an algorithm to a qgis_process command + + DummyAlgorithm alg( "test" ); + alg.runAsQgisProcessCommandChecks(); +} + +void TestQgsProcessing::asJsonMap() +{ + // test converting an algorithm to a json serializable map + + DummyAlgorithm alg( "test" ); + alg.runAsAsJsonMapChecks(); +} + void TestQgsProcessing::modelerAlgorithm() { //static value source