diff options
Diffstat (limited to 'tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp')
-rw-r--r-- | tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp | 891 |
1 files changed, 801 insertions, 90 deletions
diff --git a/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp b/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp index 4fe68e1f73..232200e633 100644 --- a/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp +++ b/tests/auto/qml/qjsprimitivevalue/tst_qjsprimitivevalue.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtCore/qobject.h> #include <QtQml/qjsengine.h> @@ -37,10 +12,30 @@ class tst_QJSPrimitiveValue : public QObject Q_OBJECT private slots: - void operators_data(); - void operators(); + void binaryOperators_data(); + void binaryOperators(); + + void unaryOperators_data(); + void unaryOperators(); void toFromVariant(); + void coercion(); + + 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(); + + void negativeNullMult(); private: QJSEngine engine; @@ -69,12 +64,14 @@ QString toScriptString(T value) else return QStringLiteral("0.0"); } + } else if (value.type() == QJSPrimitiveValue::String) { + return u'"' + value.toString() + u'"'; } return value.toString(); } } -void tst_QJSPrimitiveValue::operators_data() +void tst_QJSPrimitiveValue::binaryOperators_data() { QTest::addColumn<QJSPrimitiveValue>("lhs"); QTest::addColumn<QJSPrimitiveValue>("rhs"); @@ -96,11 +93,11 @@ do {\ #define VERBOSEVERIFY(condition, expression, js) \ QVERIFY2(condition, qPrintable(expression + " -> " + js.toString())) -enum Operator { +enum BinaryOperator { Add, Sub, Mul, Div, Eq, SEq, NEq, SNEq, GT, LT, GEq, LEq, Mod }; -QString toString(Operator op) { +QString toString(BinaryOperator op) { switch (op) { case Add: return "+"; case Sub: return "-"; @@ -117,45 +114,12 @@ QString toString(Operator op) { case Mod: return "%"; } - Q_UNREACHABLE(); - return QString(); + Q_UNREACHABLE_RETURN(QString()); } -template<typename LHS, typename RHS, typename Result, Operator op> -void doTestOperator(QJSEngine *engine, LHS lhs, RHS rhs) +template<typename Result> +void verifyResult(Result result, QJSEngine *engine, const QString &expression) { - Result result; - - if constexpr (op == Add) - result = lhs + rhs; - else if constexpr (op == Sub) - result = lhs - rhs; - else if constexpr (op == Mul) - result = lhs * rhs; - else if constexpr (op == Div) - result = lhs / rhs; - else if constexpr (op == Eq) - result = QJSPrimitiveValue(lhs).equals(rhs); - else if constexpr (op == SEq) - result = lhs == rhs; - else if constexpr (op == NEq) - result = !QJSPrimitiveValue(lhs).equals(rhs); - else if constexpr (op == SNEq) - result = lhs != rhs; - else if constexpr (op == GT) - result = lhs > rhs; - else if constexpr (op == LT) - result = lhs < rhs; - else if constexpr (op == GEq) - result = lhs >= rhs; - else if constexpr (op == LEq) - result = lhs <= rhs; - else if constexpr (op == Mod) - result = lhs % rhs; - else - QFAIL("Unkonwn operator"); - - const QString expression = toScriptString(lhs) + " " + toString(op) + " " + toScriptString(rhs); const QJSValue js = engine->evaluate(expression); if constexpr (std::is_same_v<Result, bool>) { @@ -195,36 +159,152 @@ void doTestOperator(QJSEngine *engine, LHS lhs, RHS rhs) } } +template<typename LHS, typename RHS, typename Result, BinaryOperator op> +void doTestBinaryOperator(QJSEngine *engine, LHS lhs, RHS rhs) +{ + Result result; + + if constexpr (op == Add) + result = lhs + rhs; + else if constexpr (op == Sub) + result = lhs - rhs; + else if constexpr (op == Mul) + result = lhs * rhs; + else if constexpr (op == Div) + result = lhs / rhs; + else if constexpr (op == Eq) + result = QJSPrimitiveValue(lhs).equals(rhs); + else if constexpr (op == SEq) + result = lhs == rhs; + else if constexpr (op == NEq) + result = !QJSPrimitiveValue(lhs).equals(rhs); + else if constexpr (op == SNEq) + result = lhs != rhs; + else if constexpr (op == GT) + result = lhs > rhs; + else if constexpr (op == LT) + result = lhs < rhs; + else if constexpr (op == GEq) + result = lhs >= rhs; + else if constexpr (op == LEq) + result = lhs <= rhs; + else if constexpr (op == Mod) + result = lhs % rhs; + else + QFAIL("Unkonwn operator"); + + const QString expression = toScriptString(lhs) + " " + toString(op) + " " + toScriptString(rhs); + verifyResult(result, engine, expression); +} + template<typename LHS, typename RHS> -void doTestForAllOperators(QJSEngine *engine, LHS lhs, RHS rhs) +void doTestForAllBinaryOperators(QJSEngine *engine, LHS lhs, RHS rhs) { - doTestOperator<LHS, RHS, QJSPrimitiveValue, Add>(engine, lhs, rhs); - doTestOperator<LHS, RHS, QJSPrimitiveValue, Sub>(engine, lhs, rhs); - doTestOperator<LHS, RHS, QJSPrimitiveValue, Mul>(engine, lhs, rhs); - doTestOperator<LHS, RHS, QJSPrimitiveValue, Div>(engine, lhs, rhs); - doTestOperator<LHS, RHS, QJSPrimitiveValue, Mod>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, Eq>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, SEq>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, NEq>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, SNEq>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, GT>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, LT>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, GEq>(engine, lhs, rhs); - doTestOperator<LHS, RHS, bool, LEq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, QJSPrimitiveValue, Add>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, QJSPrimitiveValue, Sub>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, QJSPrimitiveValue, Mul>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, QJSPrimitiveValue, Div>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, QJSPrimitiveValue, Mod>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, Eq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, SEq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, NEq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, SNEq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, GT>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, LT>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, GEq>(engine, lhs, rhs); + doTestBinaryOperator<LHS, RHS, bool, LEq>(engine, lhs, rhs); } -void tst_QJSPrimitiveValue::operators() +void tst_QJSPrimitiveValue::binaryOperators() { QFETCH(QJSPrimitiveValue, lhs); QFETCH(QJSPrimitiveValue, rhs); - doTestForAllOperators(&engine, lhs, rhs); - doTestForAllOperators(&engine, lhs.toString(), rhs); - doTestForAllOperators(&engine, lhs, rhs.toString()); - doTestForAllOperators(&engine, lhs.toString() + " bar", rhs); - doTestForAllOperators(&engine, lhs, rhs.toString() + " bar"); - doTestForAllOperators(&engine, "foo" + lhs.toString(), rhs); - doTestForAllOperators(&engine, lhs, "foo" + rhs.toString()); + doTestForAllBinaryOperators(&engine, lhs, rhs); + doTestForAllBinaryOperators(&engine, lhs.toString(), rhs); + doTestForAllBinaryOperators(&engine, lhs, rhs.toString()); + doTestForAllBinaryOperators(&engine, lhs.toString() + " bar", rhs); + doTestForAllBinaryOperators(&engine, lhs, rhs.toString() + " bar"); + doTestForAllBinaryOperators(&engine, "foo" + lhs.toString(), rhs); + doTestForAllBinaryOperators(&engine, lhs, "foo" + rhs.toString()); +} + +void tst_QJSPrimitiveValue::unaryOperators_data() +{ + QTest::addColumn<QJSPrimitiveValue>("operand"); + + for (const QJSPrimitiveValue &o : operands) + QTest::newRow(qPrintable(toScriptString(o))) << o; +} + +enum UnaryOperator { + Plus, Minus, PreIncrement, PostIncrement, PreDecrement, PostDecrement +}; + +QString toString(UnaryOperator op) { + switch (op) { + case Plus: + return "+"; + case Minus: + return "-"; + case PreIncrement: + case PostIncrement: + return "++"; + case PreDecrement: + case PostDecrement: + return "--"; + } + + Q_UNREACHABLE_RETURN(QString()); +} + +template<typename Result, UnaryOperator Operator> +void doTestUnaryOperator(QJSEngine *engine, QJSPrimitiveValue operand) +{ + Result result; + + // Need to get the string here as the operators change the original value + const QString asString = toScriptString(operand); + + if constexpr (Operator == Plus) + result = +operand; + else if constexpr (Operator == Minus) + result = -operand; + else if constexpr (Operator == PreIncrement) + result = ++operand; + else if constexpr (Operator == PostIncrement) + result = operand++; + else if constexpr (Operator == PreDecrement) + result = --operand; + else if constexpr (Operator == PostDecrement) + result = operand--; + else + QFAIL("Unkonwn operator"); + + const QString decl = "var a = " + asString + "; "; + const QString expression = decl + ((Operator == PostIncrement || Operator == PostDecrement) + ? (u'a' + toString(Operator)) + : (toString(Operator) + u'a')); + verifyResult(result, engine, expression); +} + +void doTestForAllUnaryOperators(QJSEngine *engine, QJSPrimitiveValue operand) +{ + doTestUnaryOperator<QJSPrimitiveValue, Plus>(engine, operand); + doTestUnaryOperator<QJSPrimitiveValue, Minus>(engine, operand); + doTestUnaryOperator<QJSPrimitiveValue, PreIncrement>(engine, operand); + doTestUnaryOperator<QJSPrimitiveValue, PostIncrement>(engine, operand); + doTestUnaryOperator<QJSPrimitiveValue, PostDecrement>(engine, operand); +} + +void tst_QJSPrimitiveValue::unaryOperators() +{ + QFETCH(QJSPrimitiveValue, operand); + + doTestForAllUnaryOperators(&engine, operand); + doTestForAllUnaryOperators(&engine, operand.toString()); + doTestForAllUnaryOperators(&engine, operand.toString() + " bar"); + doTestForAllUnaryOperators(&engine, "foo" + operand.toString()); } void tst_QJSPrimitiveValue::toFromVariant() @@ -234,25 +314,37 @@ void tst_QJSPrimitiveValue::toFromVariant() switch (operand.type()) { case QJSPrimitiveValue::Undefined: QVERIFY(!var.isValid()); + QCOMPARE(operand.metaType(), QMetaType()); + QCOMPARE(operand.data(), nullptr); break; case QJSPrimitiveValue::Null: QCOMPARE(var.typeId(), QMetaType::Nullptr); + QCOMPARE(operand.metaType(), QMetaType::fromType<std::nullptr_t>()); + QCOMPARE(operand.data(), nullptr); break; case QJSPrimitiveValue::Boolean: QCOMPARE(var.typeId(), QMetaType::Bool); QCOMPARE(var.toBool(), operand.toBoolean()); + QCOMPARE(operand.metaType(), QMetaType::fromType<bool>()); + QCOMPARE(*static_cast<const bool *>(operand.data()), operand.toBoolean()); break; case QJSPrimitiveValue::Integer: QCOMPARE(var.typeId(), QMetaType::Int); QCOMPARE(var.toInt(), operand.toInteger()); + QCOMPARE(operand.metaType(), QMetaType::fromType<int>()); + QCOMPARE(*static_cast<const int *>(operand.data()), operand.toInteger()); break; case QJSPrimitiveValue::Double: QCOMPARE(var.typeId(), QMetaType::Double); QCOMPARE(var.toDouble(), operand.toDouble()); + QCOMPARE(operand.metaType(), QMetaType::fromType<double>()); + QCOMPARE(*static_cast<const double *>(operand.data()), operand.toDouble()); break; case QJSPrimitiveValue::String: QCOMPARE(var.typeId(), QMetaType::QString); QCOMPARE(var.toString(), operand.toString()); + QCOMPARE(operand.metaType(), QMetaType::fromType<QString>()); + QCOMPARE(*static_cast<const QString *>(operand.data()), operand.toString()); break; } @@ -265,6 +357,625 @@ void tst_QJSPrimitiveValue::toFromVariant() } } +void tst_QJSPrimitiveValue::coercion() +{ + for (const QJSPrimitiveValue &operand : operands) { + QCOMPARE(operand.to<QJSPrimitiveValue::Undefined>(), QJSPrimitiveUndefined()); + QCOMPARE(operand.to<QJSPrimitiveValue::Null>(), QJSPrimitiveNull()); + QCOMPARE(operand.to<QJSPrimitiveValue::Boolean>(), operand.toBoolean()); + QCOMPARE(operand.to<QJSPrimitiveValue::Integer>(), operand.toInteger()); + QCOMPARE(operand.to<QJSPrimitiveValue::String>(), operand.toString()); + + const QJSPrimitiveValue lhs = operand.to<QJSPrimitiveValue::Double>(); + QCOMPARE(lhs.type(), QJSPrimitiveValue::Double); + const double rhs = operand.toDouble(); + if (std::isnan(rhs)) + QVERIFY(std::isnan(lhs.toDouble())); + else + QCOMPARE(lhs.toDouble(), rhs); + } +} + +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); +} + +void tst_QJSPrimitiveValue::negativeNullMult() +{ + QJSPrimitiveValue zero(0); + QJSPrimitiveValue negative(-1); + QJSPrimitiveValue positive(1); + + QCOMPARE((zero * negative).type(), QJSPrimitiveValue::Double); + QCOMPARE((negative * zero).type(), QJSPrimitiveValue::Double); + + QCOMPARE((zero * positive).type(), QJSPrimitiveValue::Integer); + QCOMPARE((positive * zero).type(), QJSPrimitiveValue::Integer); +} + QTEST_MAIN(tst_QJSPrimitiveValue) #include "tst_qjsprimitivevalue.moc" |