diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-05-21 12:19:15 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-05-27 07:53:01 +0200 |
commit | 7a5f70d6e5037334813db938eb0f4a646df512e9 (patch) | |
tree | 5d5c1c124e3e479ff243364b84615113106d690d | |
parent | 201c4fb670239a0c153d5c95dbfed0ee3a2ec243 (diff) |
Fix QQmlScriptString::isEmpty for script strings without source code
The source code is not strictly required anymore and QQmlScriptString should
return true with isEmpty() if the object is conceptually empty (not usable),
not only when the source code is empty. It can still have a valid binding id
and thus be used in QQmlExpression.
Change-Id: I777717f2217d0c46e059c382761a1044881c5978
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r-- | src/qml/qml/qqmlscriptstring.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 49 |
2 files changed, 52 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlscriptstring.cpp b/src/qml/qml/qqmlscriptstring.cpp index fd710df52f..af9d8ec265 100644 --- a/src/qml/qml/qqmlscriptstring.cpp +++ b/src/qml/qml/qqmlscriptstring.cpp @@ -126,7 +126,9 @@ Returns whether the QQmlScriptString is empty. */ bool QQmlScriptString::isEmpty() const { - return d->script.isEmpty(); + if (!d->script.isEmpty()) + return false; + return d->bindingId == -1; } /*! diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 3561635351..2ade0b2652 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -146,6 +146,7 @@ private slots: void onCompleted(); void onDestruction(); void scriptString(); + void scriptStringWithoutSourceCode(); void defaultPropertyListOrder(); void declaredPropertyValues(); void dontDoubleCallClassBegin(); @@ -1932,6 +1933,54 @@ void tst_qqmllanguage::scriptString() } } +void tst_qqmllanguage::scriptStringWithoutSourceCode() +{ + QUrl url = testFileUrl("scriptString7.qml"); + { + QQmlEnginePrivate *eng = QQmlEnginePrivate::get(&engine); + QQmlTypeData *td = eng->typeLoader.getType(url); + Q_ASSERT(td); + + QV4::CompiledData::QmlUnit *qmlUnit = td->compiledData()->qmlUnit; + Q_ASSERT(qmlUnit); + const QV4::CompiledData::Object *rootObject = qmlUnit->objectAt(qmlUnit->indexOfRootObject); + QCOMPARE(qmlUnit->header.stringAt(rootObject->inheritedTypeNameIndex), QString("MyTypeObject")); + quint32 i; + for (i = 0; i < rootObject->nBindings; ++i) { + const QV4::CompiledData::Binding *binding = rootObject->bindingTable() + i; + if (qmlUnit->header.stringAt(binding->propertyNameIndex) != QString("scriptProperty")) + continue; + QCOMPARE(binding->valueAsScriptString(&qmlUnit->header), QString("intProperty")); + const_cast<QV4::CompiledData::Binding*>(binding)->stringIndex = 0; // empty string index + QVERIFY(binding->valueAsScriptString(&qmlUnit->header).isEmpty()); + break; + } + QVERIFY(i < rootObject->nBindings); + } + QQmlComponent component(&engine, url); + VERIFY_ERRORS(0); + + MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create()); + QVERIFY(object != 0); + QQmlScriptString ss = object->scriptProperty(); + QVERIFY(!ss.isEmpty()); + QCOMPARE(ss.stringLiteral(), QString()); + bool ok; + QCOMPARE(ss.numberLiteral(&ok), qreal(0.)); + QCOMPARE(ok, false); + + const QQmlScriptStringPrivate *scriptPrivate = QQmlScriptStringPrivate::get(ss); + QVERIFY(scriptPrivate != 0); + QVERIFY(scriptPrivate->script.isEmpty()); + QCOMPARE(scriptPrivate->scope, qobject_cast<QObject*>(object)); + QCOMPARE(scriptPrivate->context, qmlContext(object)); + + { + QQmlExpression expr(ss, /*context*/0, object); + QCOMPARE(expr.evaluate().toInt(), int(100)); + } +} + // Check that default property assignments are correctly spliced into explicit // property assignments void tst_qqmllanguage::defaultPropertyListOrder() |