diff options
Diffstat (limited to 'tests/auto')
23 files changed, 636 insertions, 18 deletions
diff --git a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp index ab8fa8a9ef..476ad2e955 100644 --- a/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp +++ b/tests/auto/qml/animation/qparallelanimationgroupjob/tst_qparallelanimationgroupjob.cpp @@ -63,8 +63,8 @@ private slots: void tst_QParallelAnimationGroupJob::initTestCase() { qRegisterMetaType<QAbstractAnimationJob::State>("QAbstractAnimationJob::State"); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) - // give the mac/wince app start event queue time to clear +#if defined(Q_OS_DARWIN) + // give the Apple application's start event queue time to clear QTest::qWait(1000); #endif } diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp index b800cc3715..d1150be831 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp @@ -42,11 +42,6 @@ #include <QtCore/qlibraryinfo.h> #include <QtQml/qjsengine.h> -#if defined (Q_OS_WINCE) -#undef IN -#undef OUT -#endif - const char *V8REQUEST = "v8request"; const char *V8MESSAGE = "v8message"; const char *SEQ = "seq"; diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml new file mode 100644 index 0000000000..b64a2e23c0 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_arg.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: { + var data = new Uint8Array([1, 2, 3]); + var sum = byteArrayMethod_Sum(data.buffer); + ok = sum == 6; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml new file mode 100644 index 0000000000..9e1c91810a --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_overload.qml @@ -0,0 +1,7 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: ok = byteArrayMethod_Overloaded(new ArrayBuffer()); +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml new file mode 100644 index 0000000000..5a4f9fec0b --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_method_return.qml @@ -0,0 +1,15 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + Component.onCompleted: { + var buf = byteArrayMethod_CountUp(1, 3); + var view = new DataView(buf); + ok = buf instanceof ArrayBuffer + && buf.byteLength == 3 + && view.getUint8(0) == 1 + && view.getUint8(1) == 2 + && view.getUint8(2) == 3; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml new file mode 100644 index 0000000000..78ebb1abe1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_get.qml @@ -0,0 +1,5 @@ +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: byteArrayProperty instanceof ArrayBuffer +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml new file mode 100644 index 0000000000..e8a51273ca --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_property_set.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + onByteArraySignal: ok = byteArrayProperty instanceof ArrayBuffer + Component.onCompleted: { + byteArrayProperty = new ArrayBuffer(42); + ok = byteArrayProperty instanceof ArrayBuffer && byteArrayProperty.byteLength == 42; + } +} diff --git a/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml new file mode 100644 index 0000000000..d9f436e788 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/arraybuffer_signal_arg.qml @@ -0,0 +1,14 @@ +import QtQuick 2.7 +import Test 1.0 + +MyArrayBufferTestClass { + property bool ok: false + onByteArraySignal: { + var view = new DataView(arg); + ok = arg instanceof ArrayBuffer + && arg.byteLength == 2 + && view.getUint8(0) == 42 + && view.getUint8(1) == 43; + } + Component.onCompleted: emitByteArraySignal(42, 2) +} diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp index 9593bfc940..cc39422dce 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.cpp +++ b/tests/auto/qml/qqmllanguage/testtypes.cpp @@ -98,6 +98,8 @@ void registerTypes() qmlRegisterType<MyCompositeBaseType>("Test", 1, 0, "MyCompositeBaseType"); qmlRegisterSingletonType<MyTypeObjectSingleton>("Test", 1, 0, "MyTypeObjectSingleton", myTypeObjectSingleton); + + qmlRegisterType<MyArrayBufferTestClass>("Test", 1, 0, "MyArrayBufferTestClass"); } QVariant myCustomVariantTypeConverter(const QString &data) diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h index 082182e8e6..2344b6a03b 100644 --- a/tests/auto/qml/qqmllanguage/testtypes.h +++ b/tests/auto/qml/qqmllanguage/testtypes.h @@ -1090,6 +1090,58 @@ public: static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); } }; +class MyArrayBufferTestClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged) + +signals: + void byteArrayPropertyChanged(); + void byteArraySignal(QByteArray arg); + +public: + QByteArray byteArrayPropertyValue; + QByteArray byteArrayProperty() const { + return byteArrayPropertyValue; + } + void setByteArrayProperty(const QByteArray &v) { + byteArrayPropertyValue = v; + emit byteArrayPropertyChanged(); + } + Q_INVOKABLE void emitByteArraySignal(char begin, char num) { + byteArraySignal(byteArrayMethod_CountUp(begin, num)); + } + Q_INVOKABLE int byteArrayMethod_Sum(QByteArray arg) { + int sum = 0; + for (int i = 0; i < arg.size(); ++i) { + sum += arg[i]; + } + return sum; + } + Q_INVOKABLE QByteArray byteArrayMethod_CountUp(char begin, int num) { + QByteArray ret; + for (int i = 0; i < num; ++i) { + ret.push_back(begin++); + } + return ret; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QByteArray) { + return true; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(int) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QString) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QJSValue) { + return false; + } + Q_INVOKABLE bool byteArrayMethod_Overloaded(QVariant) { + return false; + } +}; + Q_DECLARE_METATYPE(MyEnum2Class::EnumB) Q_DECLARE_METATYPE(MyEnum1Class::EnumA) Q_DECLARE_METATYPE(Qt::TextFormat) diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index c74b4dd1f1..dd7410dfd3 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -250,6 +250,9 @@ private slots: void deleteSingletons(); + void arrayBuffer_data(); + void arrayBuffer(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -4145,6 +4148,27 @@ void tst_qqmllanguage::deleteSingletons() QVERIFY(singleton.data() == 0); } +void tst_qqmllanguage::arrayBuffer_data() +{ + QTest::addColumn<QString>("file"); + QTest::newRow("arraybuffer_property_get") << "arraybuffer_property_get.qml"; + QTest::newRow("arraybuffer_property_set") << "arraybuffer_property_set.qml"; + QTest::newRow("arraybuffer_signal_arg") << "arraybuffer_signal_arg.qml"; + QTest::newRow("arraybuffer_method_arg") << "arraybuffer_method_arg.qml"; + QTest::newRow("arraybuffer_method_return") << "arraybuffer_method_return.qml"; + QTest::newRow("arraybuffer_method_overload") << "arraybuffer_method_overload.qml"; +} + +void tst_qqmllanguage::arrayBuffer() +{ + QFETCH(QString, file); + QQmlComponent component(&engine, testFile(file)); + VERIFY_ERRORS(0); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("ok").toBool(), true); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent.qml b/tests/auto/qml/qqmlqt/data/LaterComponent.qml new file mode 100644 index 0000000000..7dbd81d93d --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/LaterComponent.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import LaterImports 1.0 + +TestElement { + id: deleteme + function testFn() { + gc(); // at this point, obj is deleted. + dangerousFunction(); // calling this function will throw an exeption + // because this object has been deleted and its context is not available + + // which means that we shouldn't get to this line. + row.test10_1 = 1; + } +} diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent2.qml b/tests/auto/qml/qqmlqt/data/LaterComponent2.qml new file mode 100644 index 0000000000..56bcc0235b --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/LaterComponent2.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Item { + id: deleteme2 + function testFn() { + // this function shouldn't be called, + // since the object will have been deleted. + var crashy = Qt.createQmlObject("import QtQuick 2.0; Item { }", deleteme2) // invalid calling context if invoked after gc + row.test11_1 = 2; + } + + Component.onDestruction: row.test11_1 = 1; // success == the object was deleted, but testFn wasn't called. +} diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent3.qml b/tests/auto/qml/qqmlqt/data/LaterComponent3.qml new file mode 100644 index 0000000000..c6f445253a --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/LaterComponent3.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +import LaterImports 1.0 + +TestElement { + id: deleteme3 + function testFn() { + gc(); // at this point, obj is deleted. + dangerousFunction(); // calling this function will throw an exeption + // because this object has been deleted and its context is not available + + // which means that we shouldn't get to this line. + row.test12_1 = 1; + } +} diff --git a/tests/auto/qml/qqmlqt/data/LaterComponent4.qml b/tests/auto/qml/qqmlqt/data/LaterComponent4.qml new file mode 100644 index 0000000000..0c53bd368b --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/LaterComponent4.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + id: deleteme4 + function testFn() { + // this function shouldn't be called, + // since the object will have been deleted. + row.test13_1 = 2; + } + + Component.onDestruction: row.test13_1 = 1; // success == the object was deleted, but testFn wasn't called. +} diff --git a/tests/auto/qml/qqmlqt/data/later.qml b/tests/auto/qml/qqmlqt/data/later.qml new file mode 100644 index 0000000000..a90f3aba9f --- /dev/null +++ b/tests/auto/qml/qqmlqt/data/later.qml @@ -0,0 +1,124 @@ +import QtQuick 2.0 +import LaterImports 1.0 + +Row { + id: row + Repeater { + id: repeater + model: 5 + delegate: Item { } + } + + property bool test1_1: false + property bool test1_2: row.focus + property bool test2_1: false + property bool test2_2: (firstFunctionCallCounter == 1 && secondFunctionCallCounter == 1 && signalCallCounter == 1) + + property int firstFunctionCallCounter: 0 + property int secondFunctionCallCounter: 0 + property int signalCallCounter: 0 + + signal testSignal + onTestSignal: { + signalCallCounter++; + } + + onChildrenChanged: { + Qt.callLater(row.forceActiveFocus); // built-in function + Qt.callLater(row.firstFunction); // JS function + Qt.callLater(row.testSignal); // signal + } + + function firstFunction() { + firstFunctionCallCounter++; + } + + function secondFunction() { + secondFunctionCallCounter++; + } + + Component.onCompleted: { + test1_1 = !row.focus; + test2_1 = (firstFunctionCallCounter == 0); + + Qt.callLater(secondFunction); + Qt.callLater(firstFunction); + Qt.callLater(secondFunction); + } + + function test2() { + repeater.model = 2; + } + + function test3() { + Qt.callLater(test3_recursive); + } + + property int recursion: 0 + property bool test3_1: (recursion == 1) + property bool test3_2: (recursion == 2) + property bool test3_3: (recursion == 3) + function test3_recursive() { + if (recursion < 3) { + Qt.callLater(test3_recursive); + Qt.callLater(test3_recursive); + } + recursion++; + } + + function test4() { + Qt.callLater(functionThatDoesNotExist); + } + + property bool test5_1: false + function test5() { + Qt.callLater(functionWithArguments, "THESE", "ARGS", "WILL", "BE", "OVERWRITTEN") + Qt.callLater(functionWithArguments, "firstArg", 2, "thirdArg") + } + + function functionWithArguments(firstStr, secondInt, thirdString) { + test5_1 = (firstStr == "firstArg" && secondInt == 2 && thirdString == "thirdArg"); + } + + + property bool test6_1: (callOrder_Later == "TWO THREE ") // not "THREE TWO " + function test6() { + Qt.callLater(test6Function1, "ONE"); + Qt.callLater(test6Function2, "TWO"); + Qt.callLater(test6Function1, "THREE"); + } + + property string callOrder_Later + function test6Function1(arg) { callOrder_Later += arg + " "; } + function test6Function2(arg) { callOrder_Later += arg + " "; } + + property int test9_1: SingletonType.intProp; + function test9() { + SingletonType.resetIntProp(); + Qt.callLater(SingletonType.testFunc) + Qt.callLater(SingletonType.testFunc) + Qt.callLater(SingletonType.testFunc) + Qt.callLater(SingletonType.testFunc) + // should only get called once. + } + + property int test10_1: 0 + function test10() { + var c = Qt.createComponent("LaterComponent.qml"); + var obj = c.createObject(); // QML ownership. + Qt.callLater(obj.testFn); + // note: obj will be cleaned up during next gc(). + } + + property int test11_1: 0 + function test11() { + var c = Qt.createComponent("LaterComponent2.qml"); + var obj = c.createObject(); // QML ownership. + Qt.callLater(obj.testFn); + gc(); // this won't actually collect the obj, we need to trigger gc manually in the test. + } + + function test14() { + Qt.callLater(console.log, "success") + } +} diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 01283dd587..413feb0eb4 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -53,6 +53,7 @@ public: tst_qqmlqt() {} private slots: + void initTestCase(); void enums(); void rgba(); void hsla(); @@ -87,11 +88,68 @@ private slots: void fontFamilies(); void quit(); void resolvedUrl(); + void later_data(); + void later(); private: QQmlEngine engine; }; +// for callLater() +class TestElement : public QQuickItem +{ + Q_OBJECT +public: + TestElement() : m_intptr(new int) {} + ~TestElement() { delete m_intptr; } + + Q_INVOKABLE void dangerousFunction() { + delete m_intptr; + m_intptr = new int; + *m_intptr = 5; + } +private: + int *m_intptr; +}; + +// for callLater() +class TestModuleApi : public QObject +{ + Q_OBJECT + Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged) + +public: + TestModuleApi() : m_int(0) {} + ~TestModuleApi() {} + + int intProp() const { return m_int; } + void setIntProp(int v) { m_int = v; emit intPropChanged(); } + + Q_INVOKABLE void testFunc() { ++m_int; emit intPropChanged(); } + Q_INVOKABLE void resetIntProp() { m_int = 0; emit intPropChanged(); } + +signals: + void intPropChanged(); + +private: + int m_int; +}; + +static QObject *test_module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + TestModuleApi *api = new TestModuleApi; + return api; +} + +void tst_qqmlqt::initTestCase() +{ + QQmlDataTest::initTestCase(); + qmlRegisterSingletonType<TestModuleApi>("LaterImports", 1, 0, "SingletonType", test_module_api_factory); + qmlRegisterType<TestElement>("LaterImports", 1, 0, "TestElement"); +} + void tst_qqmlqt::enums() { QQmlComponent component(&engine, testFileUrl("enums.qml")); @@ -934,6 +992,107 @@ void tst_qqmlqt::resolvedUrl() delete object; } +void tst_qqmlqt::later_data() +{ + QTest::addColumn<QString>("function"); + QTest::addColumn<QStringList>("expectedWarnings"); + QTest::addColumn<QStringList>("propNames"); + QTest::addColumn<QVariantList>("values"); + + QVariant vtrue = QVariant(true); + + QTest::newRow("callLater from onCompleted") + << QString() + << QStringList() + << (QStringList() << "test1_1" << "test2_1" << "processEvents" << "test1_2" << "test2_2") + << (QVariantList() << vtrue << vtrue << QVariant() << vtrue << vtrue); + + QTest::newRow("trigger Qt.callLater() via repeater") + << QString(QLatin1String("test2")) + << QStringList() + << (QStringList() << "processEvents" << "test2_2") + << (QVariantList() << QVariant() << vtrue); + + QTest::newRow("recursive Qt.callLater()") + << QString(QLatin1String("test3")) + << QStringList() + << (QStringList() << "processEvents" << "test3_1" << "processEvents" << "test3_2" << "processEvents" << "test3_3") + << (QVariantList() << QVariant() << vtrue << QVariant() << vtrue << QVariant() << vtrue); + + QTest::newRow("nonexistent function") + << QString(QLatin1String("test4")) + << (QStringList() << QString(testFileUrl("later.qml").toString() + QLatin1String(":70: ReferenceError: functionThatDoesNotExist is not defined"))) + << QStringList() + << QVariantList(); + + QTest::newRow("callLater with different args") + << QString(QLatin1String("test5")) + << QStringList() + << (QStringList() << "processEvents" << "test5_1") + << (QVariantList() << QVariant() << vtrue); + + QTest::newRow("delayed call ordering") + << QString(QLatin1String("test6")) + << QStringList() + << (QStringList() << "processEvents" << "test6_1") + << (QVariantList() << QVariant() << vtrue); + + QTest::newRow("invoke module api invokable") + << QString(QLatin1String("test9")) + << QStringList() + << (QStringList() << "processEvents" << "test9_1" << "processEvents") + << (QVariantList() << QVariant() << QVariant(1) << QVariant()); + + QTest::newRow("invoke function of deleted QObject via callLater() causing deletion") + << QString(QLatin1String("test10")) + << (QStringList() << QString(testFileUrl("LaterComponent.qml").toString() + QLatin1String(":8: ReferenceError: dangerousFunction is not defined (exception occurred during delayed function evaluation)"))) + << (QStringList() << "processEvents" << "test10_1" << "processEvents") + << (QVariantList() << QVariant() << QVariant(0) << QVariant()); + + QTest::newRow("invoke function of deleted QObject via callLater() after deletion") + << QString(QLatin1String("test11")) + << QStringList() + << (QStringList() << "collectGarbage" << "processEvents" << "test11_1" << "processEvents") + << (QVariantList() << QVariant() << QVariant() << QVariant(1) << QVariant()); + + QTest::newRow("invoke function which has no script origin") + << QString(QLatin1String("test14")) + << QStringList() + << (QStringList() << "collectGarbage") + << (QVariantList() << QVariant()); +} + +void tst_qqmlqt::later() +{ + QFETCH(QString, function); + QFETCH(QStringList, expectedWarnings); + QFETCH(QStringList, propNames); + QFETCH(QVariantList, values); + + foreach (const QString &w, expectedWarnings) + QTest::ignoreMessage(QtWarningMsg, qPrintable(w)); + + QQmlComponent component(&engine, testFileUrl("later.qml")); + QObject *root = component.create(); + QVERIFY(root != 0); + + if (!function.isEmpty()) + QMetaObject::invokeMethod(root, qPrintable(function)); + + for (int i = 0; i < propNames.size(); ++i) { + if (propNames.at(i) == QLatin1String("processEvents")) { + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + } else if (propNames.at(i) == QLatin1String("collectGarbage")) { + engine.collectGarbage(); + } else { + QCOMPARE(root->property(qPrintable(propNames.at(i))), values.at(i)); + } + } + + delete root; +} + QTEST_MAIN(tst_qqmlqt) #include "tst_qqmlqt.moc" diff --git a/tests/auto/quick/qquickaccessible/qquickaccessible.pro b/tests/auto/quick/qquickaccessible/qquickaccessible.pro index 02915e8e22..537aad882f 100644 --- a/tests/auto/quick/qquickaccessible/qquickaccessible.pro +++ b/tests/auto/quick/qquickaccessible/qquickaccessible.pro @@ -15,10 +15,3 @@ OTHER_FILES += data/checkbuttons.qml \ data/pushbutton.qml \ data/statictext.qml \ data/ignored.qml \ - -wince*: { - accessneeded.files = $$QT.widgets.plugins/accessible/*.dll - accessneeded.path = accessible - DEPLOYMENT += accessneeded -} - diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp index 1bd163fc4a..114f906736 100644 --- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp +++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp @@ -47,6 +47,7 @@ private slots: void active(); void state(); void layoutDirection(); + void font(); void inputMethod(); void styleHints(); void cleanup(); @@ -196,6 +197,21 @@ void tst_qquickapplication::layoutDirection() QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); } +void tst_qquickapplication::font() +{ + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0; Item { property font defaultFont: Qt.application.font }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); + QVERIFY(item); + QQuickView view; + item->setParentItem(view.rootObject()); + + QVariant defaultFontProperty = item->property("defaultFont"); + QVERIFY(defaultFontProperty.isValid()); + QCOMPARE(defaultFontProperty.type(), QVariant::Font); + QCOMPARE(defaultFontProperty.value<QFont>(), qApp->font()); +} + void tst_qquickapplication::inputMethod() { // technically not in QQuickApplication, but testing anyway here diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index d163ee785e..1cd3d1f9e2 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -146,6 +146,8 @@ private slots: void padding(); + void hintingPreference(); + private: QStringList standard; QStringList richText; @@ -4152,6 +4154,33 @@ void tst_qquicktext::padding() delete root; } +void tst_qquicktext::hintingPreference() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QQmlComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferDefaultHinting); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.hintingPreference: Font.PreferNoHinting }"; + QQmlComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().hintingPreference(), (int)QFont::PreferNoHinting); + + delete textObject; + } +} + + QTEST_MAIN(tst_qquicktext) #include "tst_qquicktext.moc" diff --git a/tests/auto/quick/qquicktextedit/BLACKLIST b/tests/auto/quick/qquicktextedit/BLACKLIST index 297146195b..492d81531a 100644 --- a/tests/auto/quick/qquicktextedit/BLACKLIST +++ b/tests/auto/quick/qquicktextedit/BLACKLIST @@ -1,6 +1,2 @@ [mouseSelection] * -[undo] -* -[undo_keypressevents] -* diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp index b7bfc357f3..3c899c1e34 100644 --- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp @@ -108,6 +108,7 @@ private slots: void selectionOnFocusOut(); void focusOnPress(); void selection(); + void overwriteMode(); void isRightToLeft_data(); void isRightToLeft(); void keySelection(); @@ -1467,6 +1468,74 @@ void tst_qquicktextedit::selection() QVERIFY(textEditObject->selectedText().isNull()); } +void tst_qquicktextedit::overwriteMode() +{ + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true; }"; + QQmlComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QSignalSpy spy(textEdit, SIGNAL(overwriteModeChanged(bool))); + + QQuickWindow window; + textEdit->setParentItem(window.contentItem()); + window.show(); + window.requestActivate(); + QTest::qWaitForWindowActive(&window); + + QVERIFY(textEdit->hasActiveFocus()); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 1); + QCOMPARE(true, textEdit->overwriteMode()); + textEdit->setOverwriteMode(false); + QCOMPARE(spy.count(), 2); + QCOMPARE(false, textEdit->overwriteMode()); + + QVERIFY(!textEdit->overwriteMode()); + QString insertString = "Some first text"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + + QCOMPARE(textEdit->text(), QString("Some first text")); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 3); + textEdit->setCursorPosition(5); + + insertString = "shiny"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->text(), QString("Some shiny text")); + + textEdit->setCursorPosition(textEdit->text().length()); + QTest::keyClick(&window, Qt::Key_Enter); + + textEdit->setOverwriteMode(false); + QCOMPARE(spy.count(), 4); + + insertString = "Second paragraph"; + + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->lineCount(), 2); + + textEdit->setCursorPosition(15); + + QCOMPARE(textEdit->cursorPosition(), 15); + + textEdit->setOverwriteMode(true); + QCOMPARE(spy.count(), 5); + + insertString = " blah"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textEdit->lineCount(), 2); + + QCOMPARE(textEdit->text(), QString("Some shiny text blah\nSecond paragraph")); +} + void tst_qquicktextedit::isRightToLeft_data() { QTest::addColumn<QString>("text"); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 3b4e57b2a8..e26bf6f4e4 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -105,6 +105,7 @@ private slots: void wrap(); void selection(); void persistentSelection(); + void overwriteMode(); void isRightToLeft_data(); void isRightToLeft(); void moveCursorSelection_data(); @@ -779,6 +780,48 @@ void tst_qquicktextinput::persistentSelection() QCOMPARE(input->property("selected").toString(), QLatin1String("ell")); } +void tst_qquicktextinput::overwriteMode() +{ + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; }"; + QQmlComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast<QQuickTextInput*>(textInputComponent.create()); + QVERIFY(textInput != 0); + + QSignalSpy spy(textInput, SIGNAL(overwriteModeChanged(bool))); + + QQuickWindow window; + textInput->setParentItem(window.contentItem()); + window.show(); + window.requestActivate(); + QTest::qWaitForWindowActive(&window); + + QVERIFY(textInput->hasActiveFocus()); + + textInput->setOverwriteMode(true); + QCOMPARE(spy.count(), 1); + QCOMPARE(true, textInput->overwriteMode()); + textInput->setOverwriteMode(false); + QCOMPARE(spy.count(), 2); + QCOMPARE(false, textInput->overwriteMode()); + + QVERIFY(!textInput->overwriteMode()); + QString insertString = "Some first text"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + + QCOMPARE(textInput->text(), QString("Some first text")); + + textInput->setOverwriteMode(true); + QCOMPARE(spy.count(), 3); + textInput->setCursorPosition(5); + + insertString = "shiny"; + for (int j = 0; j < insertString.length(); j++) + QTest::keyClick(&window, insertString.at(j).toLatin1()); + QCOMPARE(textInput->text(), QString("Some shiny text")); +} + void tst_qquicktextinput::isRightToLeft_data() { QTest::addColumn<QString>("text"); |