summaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp')
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp224
1 files changed, 208 insertions, 16 deletions
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 034adf7..40b0e1b 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -50,6 +50,7 @@
#include <QtCore/qnumeric.h>
#include <private/qdeclarativeengine_p.h>
#include <private/qdeclarativeglobalscriptclass_p.h>
+#include <private/qscriptdeclarativeclass_p.h>
#include "testtypes.h"
#include "testhttpserver.h"
#include "../../../shared/util.h"
@@ -105,7 +106,7 @@ private slots:
void constantsOverrideBindings();
void outerBindingOverridesInnerBinding();
void aliasPropertyAndBinding();
- void nonExistantAttachedObject();
+ void nonExistentAttachedObject();
void scope();
void signalParameterTypes();
void objectsCompareAsEqual();
@@ -142,6 +143,7 @@ private slots:
void compiled();
void numberAssignment();
void propertySplicing();
+ void signalWithUnknownTypes();
void bug1();
void bug2();
@@ -155,7 +157,10 @@ private slots:
void qtcreatorbug_1289();
void noSpuriousWarningsAtShutdown();
void canAssignNullToQObject();
- void functionAssignment();
+ void functionAssignment_fromBinding();
+ void functionAssignment_fromJS();
+ void functionAssignment_fromJS_data();
+ void functionAssignmentfromJS_invalid();
void eval();
void function();
void qtbug_10696();
@@ -170,12 +175,16 @@ private slots:
void aliasBindingsAssignCorrectly();
void aliasBindingsOverrideTarget();
void aliasWritesOverrideBindings();
+ void pushCleanContext();
void include();
void callQtInvokables();
void invokableObjectArg();
void invokableObjectRet();
+
+ void revisionErrors();
+ void revision();
private:
QDeclarativeEngine engine;
};
@@ -643,7 +652,7 @@ void tst_qdeclarativeecmascript::attachedProperties()
void tst_qdeclarativeecmascript::enums()
{
- // Existant enums
+ // Existent enums
{
QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml"));
QObject *object = component.create();
@@ -785,9 +794,9 @@ Access a non-existent attached object.
Tests for a regression where this used to crash.
*/
-void tst_qdeclarativeecmascript::nonExistantAttachedObject()
+void tst_qdeclarativeecmascript::nonExistentAttachedObject()
{
- QDeclarativeComponent component(&engine, TEST_FILE("nonExistantAttachedObject.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("nonExistentAttachedObject.qml"));
QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
@@ -2334,6 +2343,26 @@ void tst_qdeclarativeecmascript::propertySplicing()
delete object;
}
+// QTBUG-16683
+void tst_qdeclarativeecmascript::signalWithUnknownTypes()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("signalWithUnknownTypes.qml"));
+
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(object != 0);
+
+ MyQmlObject::MyType type;
+ type.value = 0x8971123;
+ emit object->signalWithUnknownType(type);
+
+ MyQmlObject::MyType result = qvariant_cast<MyQmlObject::MyType>(object->variant());
+
+ QCOMPARE(result.value, type.value);
+
+
+ delete object;
+}
+
// Test that assigning a null object works
// Regressed with: df1788b4dbbb2826ae63f26bdf166342595343f4
void tst_qdeclarativeecmascript::nullObjectBinding()
@@ -2511,9 +2540,8 @@ void tst_qdeclarativeecmascript::canAssignNullToQObject()
}
}
-void tst_qdeclarativeecmascript::functionAssignment()
+void tst_qdeclarativeecmascript::functionAssignment_fromBinding()
{
- {
QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.1.qml"));
QString url = component.url().toString();
@@ -2526,26 +2554,64 @@ void tst_qdeclarativeecmascript::functionAssignment()
QVERIFY(!o->property("a").isValid());
delete o;
- }
+}
+
+void tst_qdeclarativeecmascript::functionAssignment_fromJS()
+{
+ QFETCH(QString, triggerProperty);
- {
QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml"));
+ QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
QVERIFY(o != 0);
+ QVERIFY(!o->property("a").isValid());
+
+ o->setProperty("aNumber", QVariant(5));
+ o->setProperty(triggerProperty.toUtf8().constData(), true);
+ QCOMPARE(o->property("a"), QVariant(50));
+ o->setProperty("aNumber", QVariant(10));
+ QCOMPARE(o->property("a"), QVariant(100));
+
+ delete o;
+}
+
+void tst_qdeclarativeecmascript::functionAssignment_fromJS_data()
+{
+ QTest::addColumn<QString>("triggerProperty");
+
+ QTest::newRow("assign to property") << "assignToProperty";
+ QTest::newRow("assign to property, from JS file") << "assignToPropertyFromJsFile";
+
+ QTest::newRow("assign to value type") << "assignToValueType";
+
+ QTest::newRow("use 'this'") << "assignWithThis";
+ QTest::newRow("use 'this' from JS file") << "assignWithThisFromJsFile";
+}
+
+void tst_qdeclarativeecmascript::functionAssignmentfromJS_invalid()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("functionAssignment.2.qml"));
+ QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
+
+ MyQmlObject *o = qobject_cast<MyQmlObject *>(component.create());
+ QVERIFY(o != 0);
QVERIFY(!o->property("a").isValid());
-
+
+ o->setProperty("assignFuncWithoutReturn", true);
+ QVERIFY(!o->property("a").isValid());
+
QString url = component.url().toString();
- QString warning = url + ":10: Error: Cannot assign a function to a property.";
+ QString warning = url + ":63: Unable to assign QString to int";
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
-
- o->setProperty("runTest", true);
-
- QVERIFY(!o->property("a").isValid());
+ o->setProperty("assignWrongType", true);
+
+ warning = url + ":70: Unable to assign QString to int";
+ QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
+ o->setProperty("assignWrongTypeToValueType", true);
delete o;
- }
}
void tst_qdeclarativeecmascript::eval()
@@ -2863,6 +2929,132 @@ void tst_qdeclarativeecmascript::aliasWritesOverrideBindings()
}
}
+void tst_qdeclarativeecmascript::revisionErrors()
+{
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors.qml"));
+ QString url = component.url().toString();
+
+ QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2";
+ QString warning2 = url + ":11: ReferenceError: Can't find variable: prop2";
+ QString warning3 = url + ":13: ReferenceError: Can't find variable: method2";
+
+ QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData());
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors2.qml"));
+ QString url = component.url().toString();
+
+ // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0
+ // method2, prop2 from MyRevisionedClass not available
+ // method4, prop4 from MyRevisionedSubclass not available
+ QString warning1 = url + ":8: ReferenceError: Can't find variable: prop2";
+ QString warning2 = url + ":14: ReferenceError: Can't find variable: prop2";
+ QString warning3 = url + ":10: ReferenceError: Can't find variable: prop4";
+ QString warning4 = url + ":16: ReferenceError: Can't find variable: prop4";
+ QString warning5 = url + ":20: ReferenceError: Can't find variable: method2";
+
+ QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning4.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning5.toLatin1().constData());
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevisionErrors3.qml"));
+ QString url = component.url().toString();
+
+ // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
+ // All properties/methods available, except MyRevisionedBaseClassUnregistered rev 1
+ QString warning1 = url + ":30: ReferenceError: Can't find variable: methodD";
+ QString warning2 = url + ":10: ReferenceError: Can't find variable: propD";
+ QString warning3 = url + ":20: ReferenceError: Can't find variable: propD";
+ QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
+ QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData());
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+}
+
+void tst_qdeclarativeecmascript::revision()
+{
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision.qml"));
+ QString url = component.url().toString();
+
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision2.qml"));
+ QString url = component.url().toString();
+
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision3.qml"));
+ QString url = component.url().toString();
+
+ MyRevisionedClass *object = qobject_cast<MyRevisionedClass *>(component.create());
+ QVERIFY(object != 0);
+ }
+ // Test that non-root classes can resolve revisioned methods
+ {
+ QDeclarativeComponent component(&engine, TEST_FILE("metaobjectRevision4.qml"));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("test").toReal(), 11.);
+ delete object;
+ }
+}
+
+// Test for QScriptDeclarativeClass::pushCleanContext()
+void tst_qdeclarativeecmascript::pushCleanContext()
+{
+ QScriptEngine engine;
+ engine.globalObject().setProperty("a", 6);
+ QCOMPARE(engine.evaluate("a").toInt32(), 6);
+
+ // First confirm pushContext() behaves as we expect
+ QScriptValue object = engine.newObject();
+ object.setProperty("a", 15);
+ QScriptContext *context1 = engine.pushContext();
+ context1->pushScope(object);
+ QCOMPARE(engine.evaluate("a").toInt32(), 15);
+
+ QScriptContext *context2 = engine.pushContext();
+ Q_UNUSED(context2);
+ QCOMPARE(engine.evaluate("a").toInt32(), 15);
+ QScriptValue func1 = engine.evaluate("(function() { return a; })");
+
+ // Now check that pushCleanContext() works
+ QScriptDeclarativeClass::pushCleanContext(&engine);
+ QCOMPARE(engine.evaluate("a").toInt32(), 6);
+ QScriptValue func2 = engine.evaluate("(function() { return a; })");
+
+ engine.popContext();
+ QCOMPARE(engine.evaluate("a").toInt32(), 15);
+
+ engine.popContext();
+ QCOMPARE(engine.evaluate("a").toInt32(), 15);
+
+ engine.popContext();
+ QCOMPARE(engine.evaluate("a").toInt32(), 6);
+
+ // Check that function objects created in these contexts work
+ QCOMPARE(func1.call().toInt32(), 15);
+ QCOMPARE(func2.call().toInt32(), 6);
+}
+
QTEST_MAIN(tst_qdeclarativeecmascript)
#include "tst_qdeclarativeecmascript.moc"