aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsapi/qjsengine.cpp27
-rw-r--r--src/qml/jsapi/qjsengine.h69
-rw-r--r--src/qml/jsapi/qjsprimitivevalue.h3
-rw-r--r--tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp601
4 files changed, 700 insertions, 0 deletions
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 8b0b650c1f..d9a2abd3a9 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -792,6 +792,13 @@ QJSValue QJSEngine::globalObject() const
return QJSValuePrivate::fromReturnedValue(v->asReturnedValue());
}
+QJSPrimitiveValue QJSEngine::createPrimitive(QMetaType type, const void *ptr)
+{
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue v(scope, m_v4Engine->metaTypeToJS(type, ptr));
+ return QV4::ExecutionEngine::createPrimitive(v);
+}
+
QJSManagedValue QJSEngine::createManaged(QMetaType type, const void *ptr)
{
QJSManagedValue result(m_v4Engine);
@@ -818,6 +825,26 @@ QJSValue QJSEngine::create(int typeId, const void *ptr)
}
#endif
+bool QJSEngine::convertPrimitive(const QJSPrimitiveValue &value, QMetaType type, void *ptr)
+{
+ switch (value.type()) {
+ case QJSPrimitiveValue::Undefined:
+ return QV4::ExecutionEngine::metaTypeFromJS(QV4::Value::undefinedValue(), type, ptr);
+ case QJSPrimitiveValue::Null:
+ return QV4::ExecutionEngine::metaTypeFromJS(QV4::Value::nullValue(), type, ptr);
+ case QJSPrimitiveValue::Boolean:
+ return QV4::ExecutionEngine::metaTypeFromJS(QV4::Value::fromBoolean(value.toBoolean()), type, ptr);
+ case QJSPrimitiveValue::Integer:
+ return QV4::ExecutionEngine::metaTypeFromJS(QV4::Value::fromInt32(value.toInteger()), type, ptr);
+ case QJSPrimitiveValue::Double:
+ return QV4::ExecutionEngine::metaTypeFromJS(QV4::Value::fromDouble(value.toDouble()), type, ptr);
+ case QJSPrimitiveValue::String:
+ return convertString(value.toString(), type, ptr);
+ }
+
+ Q_UNREACHABLE_RETURN(false);
+}
+
bool QJSEngine::convertManaged(const QJSManagedValue &value, int type, void *ptr)
{
return convertManaged(value, QMetaType(type), ptr);
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 9af6fd6e7c..033f9a1690 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -66,6 +66,21 @@ public:
}
template <typename T>
+ inline QJSPrimitiveValue toPrimitiveValue(const T &value)
+ {
+ // In the common case that the argument fits into QJSPrimitiveValue, use it.
+ if constexpr (std::disjunction_v<
+ std::is_same<T, int>,
+ std::is_same<T, bool>,
+ std::is_same<T, double>,
+ std::is_same<T, QString>>) {
+ return QJSPrimitiveValue(value);
+ }
+
+ return createPrimitive(QMetaType::fromType<T>(), &value);
+ }
+
+ template <typename T>
inline T fromScriptValue(const QJSValue &value)
{
return qjsvalue_cast<T>(value);
@@ -78,6 +93,24 @@ public:
}
template <typename T>
+ inline T fromPrimitiveValue(const QJSPrimitiveValue &value)
+ {
+ if constexpr (std::is_same_v<T, int>)
+ return value.toInteger();
+ if constexpr (std::is_same_v<T, bool>)
+ return value.toBoolean();
+ if constexpr (std::is_same_v<T, double>)
+ return value.toDouble();
+ if constexpr (std::is_same_v<T, QString>)
+ return value.toString();
+ if constexpr (std::is_same_v<T, QVariant>)
+ return value.toVariant();
+ if constexpr (std::is_pointer_v<T>)
+ return nullptr;
+ return qjsvalue_cast<T>(value);
+ }
+
+ template <typename T>
inline T fromVariant(const QVariant &value)
{
if constexpr (std::is_same_v<T, QVariant>)
@@ -101,6 +134,9 @@ public:
if constexpr (std::is_same_v<T, QJSManagedValue>)
return toManagedValue(value);
+ if constexpr (std::is_same_v<T, QJSPrimitiveValue>)
+ return toPrimitiveValue(value);
+
if constexpr (std::is_same_v<T, QString>) {
if (targetType.flags() & QMetaType::PointerToQObject) {
return convertQObjectToString(
@@ -116,6 +152,10 @@ public:
*reinterpret_cast<const QJSManagedValue *>(value.constData()));
}
+ if (sourceType == QMetaType::fromType<QJSPrimitiveValue>()) {
+ return fromPrimitiveValue<T>(
+ *reinterpret_cast<const QJSPrimitiveValue *>(value.constData()));
+ }
{
T t{};
@@ -149,6 +189,12 @@ public:
if constexpr (std::is_same_v<From, QJSManagedValue>)
return fromManagedValue<To>(from);
+ if constexpr (std::is_same_v<To, QJSPrimitiveValue>)
+ return toPrimitiveValue(from);
+
+ if constexpr (std::is_same_v<From, QJSPrimitiveValue>)
+ return fromPrimitiveValue<To>(from);
+
if constexpr (std::is_same_v<From, QVariant>)
return fromVariant<To>(from);
@@ -216,12 +262,14 @@ Q_SIGNALS:
void uiLanguageChanged();
private:
+ QJSPrimitiveValue createPrimitive(QMetaType type, const void *ptr);
QJSManagedValue createManaged(QMetaType type, const void *ptr);
QJSValue create(QMetaType type, const void *ptr);
#if QT_VERSION < QT_VERSION_CHECK(7,0,0)
QJSValue create(int id, const void *ptr); // only there for BC reasons
#endif
+ static bool convertPrimitive(const QJSPrimitiveValue &value, QMetaType type, void *ptr);
static bool convertManaged(const QJSManagedValue &value, int type, void *ptr);
static bool convertManaged(const QJSManagedValue &value, QMetaType type, void *ptr);
#if QT_VERSION < QT_VERSION_CHECK(7,0,0)
@@ -240,6 +288,9 @@ private:
template<typename T>
friend inline T qjsvalue_cast(const QJSManagedValue &);
+ template<typename T>
+ friend inline T qjsvalue_cast(const QJSPrimitiveValue &);
+
protected:
QJSEngine(QJSEnginePrivate &dd, QObject *parent = nullptr);
@@ -275,6 +326,18 @@ T qjsvalue_cast(const QJSManagedValue &value)
return qvariant_cast<T>(value.toVariant());
}
+template<typename T>
+T qjsvalue_cast(const QJSPrimitiveValue &value)
+{
+ {
+ T t;
+ if (QJSEngine::convertPrimitive(value, QMetaType::fromType<T>(), &t))
+ return t;
+ }
+
+ return qvariant_cast<T>(value.toVariant());
+}
+
template <>
inline QVariant qjsvalue_cast<QVariant>(const QJSValue &value)
{
@@ -287,6 +350,12 @@ inline QVariant qjsvalue_cast<QVariant>(const QJSManagedValue &value)
return value.toVariant();
}
+template <>
+inline QVariant qjsvalue_cast<QVariant>(const QJSPrimitiveValue &value)
+{
+ return value.toVariant();
+}
+
Q_QML_EXPORT QJSEngine *qjsEngine(const QObject *);
QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsprimitivevalue.h b/src/qml/jsapi/qjsprimitivevalue.h
index 9ac12dc86a..93a3d0ff00 100644
--- a/src/qml/jsapi/qjsprimitivevalue.h
+++ b/src/qml/jsapi/qjsprimitivevalue.h
@@ -119,6 +119,9 @@ public:
constexpr Type type() const { return Type(d.type()); }
+ // Prevent casting from Type to int
+ QJSPrimitiveValue(Type) = delete;
+
Q_IMPLICIT constexpr QJSPrimitiveValue() noexcept = default;
Q_IMPLICIT constexpr QJSPrimitiveValue(QJSPrimitiveUndefined undefined) noexcept : d(undefined) {}
Q_IMPLICIT constexpr QJSPrimitiveValue(QJSPrimitiveNull null) noexcept : d(null) {}
diff --git a/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp b/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp
index 0c46fc9f6b..2677dae17e 100644
--- a/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp
+++ b/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp
@@ -20,6 +20,20 @@ private slots:
void toFromVariant();
+ void ctor_invalid();
+ void ctor_undefinedWithEngine();
+ void ctor_boolWithEngine();
+ void ctor_intWithEngine();
+ void ctor_stringWithEngine();
+ void ctor_copyAndAssignWithEngine();
+ void toString();
+ void toNumber();
+ void toBoolean();
+ void toVariant();
+ void equals();
+ void strictlyEquals();
+ void stringAndUrl();
+
private:
QJSEngine engine;
@@ -328,6 +342,593 @@ void tst_QJSPrimitiveValue::toFromVariant()
}
}
+void tst_QJSPrimitiveValue::ctor_invalid()
+{
+ QJSPrimitiveValue v;
+ QCOMPARE(v.type(), QJSPrimitiveValue::Undefined);
+}
+
+void tst_QJSPrimitiveValue::ctor_undefinedWithEngine()
+{
+ QJSEngine eng;
+ QJSPrimitiveValue v(eng.toPrimitiveValue(QVariant()));
+ QCOMPARE(v.type(), QJSPrimitiveValue::Undefined);
+}
+
+void tst_QJSPrimitiveValue::ctor_boolWithEngine()
+{
+ QJSEngine eng;
+ QJSPrimitiveValue v(eng.toPrimitiveValue(false));
+ QCOMPARE(v.type(), QJSPrimitiveValue::Boolean);
+ QCOMPARE(v.toBoolean(), false);
+}
+
+void tst_QJSPrimitiveValue::ctor_intWithEngine()
+{
+ QJSEngine eng;
+ QJSPrimitiveValue v(eng.toPrimitiveValue(int(1)));
+ QCOMPARE(v.type(), QJSPrimitiveValue::Integer);
+ QCOMPARE(v.toInteger(), 1);
+}
+
+void tst_QJSPrimitiveValue::ctor_stringWithEngine()
+{
+ QJSEngine eng;
+ QJSPrimitiveValue v(eng.toPrimitiveValue(QStringLiteral("ciao")));
+ QCOMPARE(v.type(), QJSPrimitiveValue::String);
+ QCOMPARE(v.toString(), QStringLiteral("ciao"));
+}
+
+void tst_QJSPrimitiveValue::ctor_copyAndAssignWithEngine()
+{
+ QJSEngine eng;
+ // copy constructor, operator=
+
+ QJSPrimitiveValue v(eng.toPrimitiveValue(1.0));
+ QJSPrimitiveValue v2(v);
+ QCOMPARE(v2.strictlyEquals(v), true);
+
+ QJSPrimitiveValue v3(v);
+ QCOMPARE(v3.strictlyEquals(v), true);
+ QCOMPARE(v3.strictlyEquals(v2), true);
+
+ QJSPrimitiveValue v4(eng.toPrimitiveValue(2.0));
+ QCOMPARE(v4.strictlyEquals(v), false);
+ v3 = QJSPrimitiveValue(v4);
+ QCOMPARE(v3.strictlyEquals(v), false);
+ QCOMPARE(v3.strictlyEquals(v4), true);
+
+ v2 = QJSPrimitiveValue();
+ QCOMPARE(v2.strictlyEquals(v), false);
+ QCOMPARE(v.toDouble(), 1.0);
+
+ QJSPrimitiveValue v5(v);
+ QCOMPARE(v5.strictlyEquals(v), true);
+ v = QJSPrimitiveValue();
+ QCOMPARE(v5.strictlyEquals(v), false);
+ QCOMPARE(v5.toDouble(), 1.0);
+}
+
+void tst_QJSPrimitiveValue::toString()
+{
+ QJSEngine eng;
+
+ {
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QCOMPARE(undefined.toString(), QStringLiteral("undefined"));
+ QCOMPARE(qjsvalue_cast<QString>(undefined), QStringLiteral("undefined"));
+ }
+
+ {
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(null.toString(), QStringLiteral("null"));
+ QCOMPARE(qjsvalue_cast<QString>(null), QStringLiteral("null"));
+ }
+
+ {
+ QJSPrimitiveValue falskt(eng.toPrimitiveValue(false));
+ QCOMPARE(falskt.toString(), QStringLiteral("false"));
+ QCOMPARE(qjsvalue_cast<QString>(falskt), QStringLiteral("false"));
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QCOMPARE(sant.toString(), QStringLiteral("true"));
+ QCOMPARE(qjsvalue_cast<QString>(sant), QStringLiteral("true"));
+ }
+ {
+ QJSPrimitiveValue number(eng.toPrimitiveValue(123));
+ QCOMPARE(number.toString(), QStringLiteral("123"));
+ QCOMPARE(qjsvalue_cast<QString>(number), QStringLiteral("123"));
+ }
+ {
+ QJSPrimitiveValue number(eng.toPrimitiveValue(6.37e-8));
+ QCOMPARE(number.toString(), QStringLiteral("6.37e-8"));
+ }
+ {
+ QJSPrimitiveValue number(eng.toPrimitiveValue(-6.37e-8));
+ QCOMPARE(number.toString(), QStringLiteral("-6.37e-8"));
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("ciao")));
+ QCOMPARE(str.toString(), QStringLiteral("ciao"));
+ QCOMPARE(qjsvalue_cast<QString>(str), QStringLiteral("ciao"));
+ }
+
+ QJSPrimitiveValue inv((QJSPrimitiveUndefined()));
+ QCOMPARE(inv.toString(), QStringLiteral("undefined"));
+
+ // Type cannot be represented in QJSPrimitiveValue, and is converted to string.
+ QJSPrimitiveValue variant(eng.toPrimitiveValue(QPoint(10, 20)));
+ QCOMPARE(variant.type(), QJSPrimitiveValue::String);
+ QCOMPARE(variant.toString(), QStringLiteral("QPoint(10, 20)"));
+ variant = eng.toPrimitiveValue(QUrl());
+ QCOMPARE(variant.type(), QJSPrimitiveValue::String);
+ QVERIFY(variant.toString().isEmpty());
+
+ {
+ QByteArray hello = QByteArrayLiteral("Hello World");
+ QJSPrimitiveValue jsValue(eng.toPrimitiveValue(hello));
+ QCOMPARE(jsValue.toString(), QString::fromUtf8(hello));
+ }
+}
+
+void tst_QJSPrimitiveValue::toNumber()
+{
+ QJSEngine eng;
+
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QCOMPARE(qIsNaN(undefined.toDouble()), true);
+ QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(undefined)), true);
+
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(null.toDouble(), 0.0);
+ QCOMPARE(qjsvalue_cast<qreal>(null), 0.0);
+
+ {
+ QJSPrimitiveValue falskt(eng.toPrimitiveValue(false));
+ QCOMPARE(falskt.toDouble(), 0.0);
+ QCOMPARE(qjsvalue_cast<qreal>(falskt), 0.0);
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QCOMPARE(sant.toDouble(), 1.0);
+ QCOMPARE(qjsvalue_cast<qreal>(sant), 1.0);
+
+ QJSPrimitiveValue number(eng.toPrimitiveValue(123.0));
+ QCOMPARE(number.toDouble(), 123.0);
+ QCOMPARE(qjsvalue_cast<qreal>(number), 123.0);
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("ciao")));
+ QCOMPARE(qIsNaN(str.toDouble()), true);
+ QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(str)), true);
+
+ QJSPrimitiveValue str2(eng.toPrimitiveValue(QStringLiteral("123")));
+ QCOMPARE(str2.toDouble(), 123.0);
+ QCOMPARE(qjsvalue_cast<qreal>(str2), 123.0);
+ }
+
+ QJSPrimitiveValue inv((QJSPrimitiveUndefined()));
+ QVERIFY(qIsNaN(inv.toDouble()));
+ QVERIFY(qIsNaN(qjsvalue_cast<qreal>(inv)));
+
+ // V2 constructors
+ {
+ QJSPrimitiveValue falskt(false);
+ QCOMPARE(falskt.toDouble(), 0.0);
+ QCOMPARE(qjsvalue_cast<qreal>(falskt), 0.0);
+
+ QJSPrimitiveValue sant(true);
+ QCOMPARE(sant.toDouble(), 1.0);
+ QCOMPARE(qjsvalue_cast<qreal>(sant), 1.0);
+
+ QJSPrimitiveValue number(123.0);
+ QCOMPARE(number.toDouble(), 123.0);
+ QCOMPARE(qjsvalue_cast<qreal>(number), 123.0);
+
+ QJSPrimitiveValue number2(int(0x43211234));
+ QCOMPARE(number2.toDouble(), 1126240820.0);
+
+ QJSPrimitiveValue str(QStringLiteral("ciao"));
+ QCOMPARE(qIsNaN(str.toDouble()), true);
+ QCOMPARE(qIsNaN(qjsvalue_cast<qreal>(str)), true);
+
+ QJSPrimitiveValue str2(QStringLiteral("123"));
+ QCOMPARE(str2.toDouble(), 123.0);
+ QCOMPARE(qjsvalue_cast<qreal>(str2), 123.0);
+ }
+}
+
+void tst_QJSPrimitiveValue::toBoolean()
+{
+ QJSEngine eng;
+
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QCOMPARE(undefined.type(), QJSPrimitiveValue::Undefined);
+ QCOMPARE(undefined.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(undefined), false);
+
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(null.type(), QJSPrimitiveValue::Null);
+ QCOMPARE(null.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(null), false);
+
+ {
+ QJSPrimitiveValue falskt = eng.toPrimitiveValue(false);
+ QCOMPARE(falskt.type(), QJSPrimitiveValue::Boolean);
+ QCOMPARE(falskt.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(falskt), false);
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QCOMPARE(sant.type(), QJSPrimitiveValue::Boolean);
+ QCOMPARE(sant.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(sant), true);
+
+ QJSPrimitiveValue number(eng.toPrimitiveValue(0.0));
+ QCOMPARE(number.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(number), false);
+
+ QJSPrimitiveValue number2(eng.toPrimitiveValue(qQNaN()));
+ QCOMPARE(number2.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(number2), false);
+
+ QJSPrimitiveValue number3(eng.toPrimitiveValue(123.0));
+ QCOMPARE(number3.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(number3), true);
+
+ QJSPrimitiveValue number4(eng.toPrimitiveValue(-456.0));
+ QCOMPARE(number4.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(number4), true);
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("")));
+ QCOMPARE(str.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(str), false);
+
+ QJSPrimitiveValue str2(eng.toPrimitiveValue(QStringLiteral("123")));
+ QCOMPARE(str2.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(str2), true);
+ }
+
+ QJSPrimitiveValue inv((QJSPrimitiveUndefined()));
+ QCOMPARE(inv.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(inv), false);
+
+ // V2 constructors
+ {
+ QJSPrimitiveValue falskt(false);
+ QCOMPARE(falskt.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(falskt), false);
+
+ QJSPrimitiveValue sant(true);
+ QCOMPARE(sant.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(sant), true);
+
+ QJSPrimitiveValue number(0.0);
+ QCOMPARE(number.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(number), false);
+
+ QJSPrimitiveValue number2(qQNaN());
+ QCOMPARE(number2.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(number2), false);
+
+ QJSPrimitiveValue number3(123.0);
+ QCOMPARE(number3.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(number3), true);
+
+ QJSPrimitiveValue number4(-456.0);
+ QCOMPARE(number4.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(number4), true);
+
+ QJSPrimitiveValue number5(0x43211234);
+ QCOMPARE(number5.toBoolean(), true);
+
+ QJSPrimitiveValue str(QStringLiteral(""));
+ QCOMPARE(str.toBoolean(), false);
+ QCOMPARE(qjsvalue_cast<bool>(str), false);
+
+ QJSPrimitiveValue str2(QStringLiteral("123"));
+ QCOMPARE(str2.toBoolean(), true);
+ QCOMPARE(qjsvalue_cast<bool>(str2), true);
+ }
+}
+
+void tst_QJSPrimitiveValue::toVariant()
+{
+ QJSEngine eng;
+
+ {
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QCOMPARE(undefined.toVariant(), QVariant());
+ QCOMPARE(qjsvalue_cast<QVariant>(undefined), QVariant());
+ }
+
+ {
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(null.toVariant(), QVariant::fromValue(nullptr));
+ QCOMPARE(qjsvalue_cast<QVariant>(null), QVariant::fromValue(nullptr));
+ }
+
+ {
+ QJSPrimitiveValue number(eng.toPrimitiveValue(123.0));
+ QCOMPARE(number.toVariant(), QVariant(123.0));
+ QCOMPARE(qjsvalue_cast<QVariant>(number), QVariant(123.0));
+
+ QJSPrimitiveValue intNumber(eng.toPrimitiveValue(qint32(123)));
+ QCOMPARE(intNumber.toVariant().typeId(), QVariant((qint32)123).typeId());
+ QCOMPARE((qjsvalue_cast<QVariant>(intNumber)).typeId(),
+ QVariant(qint32(123)).typeId());
+
+ QJSPrimitiveValue falskt(eng.toPrimitiveValue(false));
+ QCOMPARE(falskt.toVariant(), QVariant(false));
+ QCOMPARE(qjsvalue_cast<QVariant>(falskt), QVariant(false));
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QCOMPARE(sant.toVariant(), QVariant(true));
+ QCOMPARE(qjsvalue_cast<QVariant>(sant), QVariant(true));
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("ciao")));
+ QCOMPARE(str.toVariant(), QVariant(QStringLiteral("ciao")));
+ QCOMPARE(qjsvalue_cast<QVariant>(str), QVariant(QStringLiteral("ciao")));
+ }
+
+ {
+ QDateTime dateTime = QDate(1980, 10, 4).startOfDay();
+ QJSPrimitiveValue dateObject(eng.toPrimitiveValue(dateTime));
+ QVariant var = dateObject.toVariant();
+ QCOMPARE(var, (eng.coerceValue<QDateTime, QString>(dateTime)));
+ QCOMPARE(dateObject.toVariant(), var);
+ }
+
+ {
+ QRegularExpression rx = QRegularExpression(QStringLiteral("[0-9a-z]+"));
+ QJSPrimitiveValue rxObject(eng.toPrimitiveValue(rx));
+ QCOMPARE(rxObject.type(), QJSPrimitiveValue::String);
+ QVariant var = rxObject.toVariant();
+ QCOMPARE(var, u'/' + rx.pattern() + u'/');
+ }
+
+ {
+ QJSPrimitiveValue inv;
+ QCOMPARE(inv.toVariant(), QVariant());
+ QCOMPARE(inv.toVariant(), QVariant());
+ QCOMPARE(qjsvalue_cast<QVariant>(inv), QVariant());
+ }
+
+ // V2 constructors
+ {
+ QJSPrimitiveValue number(123.0);
+ QCOMPARE(number.toVariant(), QVariant(123.0));
+ QCOMPARE(number.toVariant(), QVariant(123.0));
+ QCOMPARE(qjsvalue_cast<QVariant>(number), QVariant(123.0));
+
+ QJSPrimitiveValue falskt(false);
+ QCOMPARE(falskt.toVariant(), QVariant(false));
+ QCOMPARE(falskt.toVariant(), QVariant(false));
+ QCOMPARE(qjsvalue_cast<QVariant>(falskt), QVariant(false));
+
+ QJSPrimitiveValue sant(true);
+ QCOMPARE(sant.toVariant(), QVariant(true));
+ QCOMPARE(sant.toVariant(), QVariant(true));
+ QCOMPARE(qjsvalue_cast<QVariant>(sant), QVariant(true));
+
+ QJSPrimitiveValue str(QStringLiteral("ciao"));
+ QCOMPARE(str.toVariant(), QVariant(QStringLiteral("ciao")));
+ QCOMPARE(str.toVariant(), QVariant(QStringLiteral("ciao")));
+ QCOMPARE(qjsvalue_cast<QVariant>(str), QVariant(QStringLiteral("ciao")));
+
+ QJSPrimitiveValue undef((QJSPrimitiveUndefined()));
+ QCOMPARE(undef.toVariant(), QVariant());
+ QCOMPARE(undef.toVariant(), QVariant());
+ QCOMPARE(qjsvalue_cast<QVariant>(undef), QVariant());
+
+ QJSPrimitiveValue nil((QJSPrimitiveNull()));
+ QCOMPARE(nil.toVariant(), QVariant::fromValue(nullptr));
+ QCOMPARE(nil.toVariant(), QVariant::fromValue(nullptr));
+ QCOMPARE(qjsvalue_cast<QVariant>(nil), QVariant::fromValue(nullptr));
+ }
+}
+
+void tst_QJSPrimitiveValue::equals()
+{
+ QJSEngine eng;
+ QObject temp;
+
+ QVERIFY(QJSPrimitiveValue().equals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue num(eng.toPrimitiveValue(123));
+ QVERIFY(num.equals(eng.toPrimitiveValue(123)));
+ QVERIFY(!num.equals(eng.toPrimitiveValue(321)));
+ QVERIFY(num.equals(eng.toPrimitiveValue(QStringLiteral("123"))));
+ QVERIFY(!num.equals(eng.toPrimitiveValue(QStringLiteral("321"))));
+ QVERIFY(!num.equals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("123")));
+ QVERIFY(str.equals(eng.toPrimitiveValue(QStringLiteral("123"))));
+ QVERIFY(!str.equals(eng.toPrimitiveValue(QStringLiteral("321"))));
+ QVERIFY(str.equals(eng.toPrimitiveValue(123)));
+ QVERIFY(!str.equals(eng.toPrimitiveValue(321)));
+ QCOMPARE(str.equals(QJSPrimitiveValue()), false);
+
+ QJSPrimitiveValue num2(123);
+ QVERIFY(num2.equals(QJSPrimitiveValue(123)));
+ QVERIFY(!num2.equals(QJSPrimitiveValue(321)));
+ QVERIFY(num2.equals(QStringLiteral("123")));
+ QVERIFY(!num2.equals(QStringLiteral("321")));
+ QVERIFY(!num2.equals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue str2(QStringLiteral("123"));
+ QVERIFY(str2.equals(QStringLiteral("123")));
+ QVERIFY(!str2.equals(QStringLiteral("321")));
+ QVERIFY(str2.equals(QJSPrimitiveValue(123)));
+ QVERIFY(!str2.equals(QJSPrimitiveValue(321)));
+ QVERIFY(!str2.equals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue date1(eng.toPrimitiveValue(QDate(2000, 1, 1).startOfDay()));
+ QJSPrimitiveValue date2(eng.toPrimitiveValue(QDate(1999, 1, 1).startOfDay()));
+ QCOMPARE(date1.equals(date2), false);
+ QCOMPARE(date1.equals(date1), true);
+ QCOMPARE(date2.equals(date2), true);
+
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(undefined.equals(undefined), true);
+ QCOMPARE(null.equals(null), true);
+ QCOMPARE(undefined.equals(null), true);
+ QCOMPARE(null.equals(undefined), true);
+ QVERIFY(undefined.equals(QJSPrimitiveValue()));
+ QVERIFY(null.equals(QJSPrimitiveValue()));
+ QVERIFY(!null.equals(num));
+ QVERIFY(!undefined.equals(num));
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QVERIFY(sant.equals(eng.toPrimitiveValue(1)));
+ QVERIFY(sant.equals(eng.toPrimitiveValue(QStringLiteral("1"))));
+ QVERIFY(sant.equals(sant));
+ QVERIFY(!sant.equals(eng.toPrimitiveValue(0)));
+ QVERIFY(!sant.equals(undefined));
+ QVERIFY(!sant.equals(null));
+
+ QJSPrimitiveValue falskt(eng.toPrimitiveValue(false));
+ QVERIFY(falskt.equals(eng.toPrimitiveValue(0)));
+ QVERIFY(falskt.equals(eng.toPrimitiveValue(QStringLiteral("0"))));
+ QVERIFY(falskt.equals(falskt));
+ QVERIFY(!falskt.equals(sant));
+ QVERIFY(!falskt.equals(undefined));
+ QVERIFY(!falskt.equals(null));
+
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QVERIFY(var1.equals(var2));
+ }
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant::fromValue(QPoint(3, 4))));
+ QVERIFY(!var1.equals(var2));
+ }
+}
+
+void tst_QJSPrimitiveValue::strictlyEquals()
+{
+ QJSEngine eng;
+ QObject temp;
+
+ QVERIFY(QJSPrimitiveValue().strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue num(eng.toPrimitiveValue(123));
+ QVERIFY(num.strictlyEquals(eng.toPrimitiveValue(123)));
+ QVERIFY(!num.strictlyEquals(eng.toPrimitiveValue(321)));
+ QVERIFY(!num.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("123"))));
+ QVERIFY(!num.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("321"))));
+ QVERIFY(!num.strictlyEquals(QJSPrimitiveValue()));
+ QVERIFY(!QJSPrimitiveValue().strictlyEquals(num));
+
+ QJSPrimitiveValue str(eng.toPrimitiveValue(QStringLiteral("123")));
+ QVERIFY(str.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("123"))));
+ QVERIFY(!str.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("321"))));
+ QVERIFY(!str.strictlyEquals(eng.toPrimitiveValue(123)));
+ QVERIFY(!str.strictlyEquals(eng.toPrimitiveValue(321)));
+ QVERIFY(!str.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue num2(123);
+ QVERIFY(num2.strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!num2.strictlyEquals(QJSPrimitiveValue(321)));
+ QVERIFY(!num2.strictlyEquals(QStringLiteral("123")));
+ QVERIFY(!num2.strictlyEquals(QStringLiteral("321")));
+ QVERIFY(!num2.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue str2(QStringLiteral("123"));
+ QVERIFY(str2.strictlyEquals(QStringLiteral("123")));
+ QVERIFY(!str2.strictlyEquals(QStringLiteral("321")));
+ QVERIFY(!str2.strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!str2.strictlyEquals(QJSPrimitiveValue(321)));
+ QVERIFY(!str2.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue date1(eng.toPrimitiveValue(QDate(2000, 1, 1).startOfDay()));
+ QJSPrimitiveValue date2(eng.toPrimitiveValue(QDate(1999, 1, 1).startOfDay()));
+ QCOMPARE(date1.strictlyEquals(date2), false);
+ QCOMPARE(date1.strictlyEquals(date1), true);
+ QCOMPARE(date2.strictlyEquals(date2), true);
+ QVERIFY(!date1.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue undefined(eng.toPrimitiveValue(QVariant()));
+ QJSPrimitiveValue null((QJSPrimitiveNull()));
+ QCOMPARE(undefined.strictlyEquals(undefined), true);
+ QCOMPARE(null.strictlyEquals(null), true);
+ QCOMPARE(undefined.strictlyEquals(null), false);
+ QCOMPARE(null.strictlyEquals(undefined), false);
+ QVERIFY(!null.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue sant(eng.toPrimitiveValue(true));
+ QVERIFY(!sant.strictlyEquals(eng.toPrimitiveValue(1)));
+ QVERIFY(!sant.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("1"))));
+ QVERIFY(sant.strictlyEquals(sant));
+ QVERIFY(!sant.strictlyEquals(eng.toPrimitiveValue(0)));
+ QVERIFY(!sant.strictlyEquals(undefined));
+ QVERIFY(!sant.strictlyEquals(null));
+ QVERIFY(!sant.strictlyEquals(QJSPrimitiveValue()));
+
+ QJSPrimitiveValue falskt(eng.toPrimitiveValue(false));
+ QVERIFY(!falskt.strictlyEquals(eng.toPrimitiveValue(0)));
+ QVERIFY(!falskt.strictlyEquals(eng.toPrimitiveValue(QStringLiteral("0"))));
+ QVERIFY(falskt.strictlyEquals(falskt));
+ QVERIFY(!falskt.strictlyEquals(sant));
+ QVERIFY(!falskt.strictlyEquals(undefined));
+ QVERIFY(!falskt.strictlyEquals(null));
+ QVERIFY(!falskt.strictlyEquals(QJSPrimitiveValue()));
+
+ QVERIFY(!QJSPrimitiveValue(false).strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!QJSPrimitiveValue(QJSPrimitiveUndefined()).strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!QJSPrimitiveValue(QJSPrimitiveNull()).strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!QJSPrimitiveValue(false).strictlyEquals({QStringLiteral("ciao")}));
+ QVERIFY(!QJSPrimitiveValue(QJSPrimitiveUndefined()).strictlyEquals({QStringLiteral("ciao")}));
+ QVERIFY(!QJSPrimitiveValue(QJSPrimitiveNull()).strictlyEquals({QStringLiteral("ciao")}));
+ QVERIFY(eng.toPrimitiveValue(QStringLiteral("ciao")).strictlyEquals(QJSPrimitiveValue(QStringLiteral("ciao"))));
+ QVERIFY(QJSPrimitiveValue(QStringLiteral("ciao")).strictlyEquals(eng.toPrimitiveValue(QStringLiteral("ciao"))));
+ QVERIFY(!QJSPrimitiveValue(QStringLiteral("ciao")).strictlyEquals(QJSPrimitiveValue(123)));
+ QVERIFY(!QJSPrimitiveValue(QStringLiteral("ciao")).strictlyEquals(eng.toPrimitiveValue(123)));
+ QVERIFY(!QJSPrimitiveValue(123).strictlyEquals({QStringLiteral("ciao")}));
+ QVERIFY(!QJSPrimitiveValue(123).strictlyEquals(eng.toPrimitiveValue(QStringLiteral("ciao"))));
+ QVERIFY(!eng.toPrimitiveValue(123).strictlyEquals(QJSPrimitiveValue(QStringLiteral("ciao"))));
+
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant(QStringList() << QStringLiteral("a"))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant(QStringList() << QStringLiteral("a"))));
+ QVERIFY(var1.strictlyEquals(var2));
+ }
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant(QStringList() << QStringLiteral("a"))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant(QStringList() << QStringLiteral("b"))));
+ QVERIFY(!var1.strictlyEquals(var2));
+ }
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QVERIFY(var1.strictlyEquals(var2));
+ }
+ {
+ QJSPrimitiveValue var1(eng.toPrimitiveValue(QVariant::fromValue(QPoint(1, 2))));
+ QJSPrimitiveValue var2(eng.toPrimitiveValue(QVariant::fromValue(QPoint(3, 4))));
+ QVERIFY(!var1.strictlyEquals(var2));
+ }
+}
+
+void tst_QJSPrimitiveValue::stringAndUrl()
+{
+ QJSEngine engine;
+ const QString string = QStringLiteral("http://example.com/something.html");
+ const QUrl url(string);
+
+ const QJSPrimitiveValue urlValue(engine.toPrimitiveValue(url));
+ QCOMPARE(urlValue.type(), QJSPrimitiveValue::String);
+ QCOMPARE(urlValue.toString(), string);
+ QCOMPARE(engine.fromPrimitiveValue<QUrl>(urlValue), url);
+
+ const QJSPrimitiveValue stringValue(engine.toPrimitiveValue(string));
+ QCOMPARE(stringValue.toString(), string);
+ QCOMPARE(engine.fromPrimitiveValue<QUrl>(stringValue), url);
+
+ const QJSPrimitiveValue immediateStringValue(string);
+ QCOMPARE(immediateStringValue.toString(), string);
+ QCOMPARE(engine.fromPrimitiveValue<QUrl>(immediateStringValue), url);
+}
+
QTEST_MAIN(tst_QJSPrimitiveValue)
#include "tst_qjsprimitivevalue.moc"