2022-05-13 13:12:05 +00:00
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
Mark the module as free of Q_FOREACH, except where it isn't
The density of Q_FOREACH uses is high here, too high for this author,
unfamiliar with this code, to tackle in a short amount of time. But
they're concentrated in just a few TUs, so pick a different strategy:
Mark the whole module with QT_NO_FOREACH, to prevent new uses from
creeping in, and whitelist the affected TUs by #undef'ing
QT_NO_FOREACH locally, at the top of each file. For TUs that are part
of a larger executable, this requires these files to be compiled
separately, so add them to NO_PCH_SOURCES (which implies
NO_UNITY_BUILD_SOURCES, too). Created QTBUG-115808 to keep track of
this.
Task-number: QTBUG-115808
Change-Id: I29c377f939e3d747e3ce72c224c4ee722df7a95d
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2023-08-06 15:03:37 +00:00
# undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
2011-04-27 12:13:26 +00:00
# include <qtest.h>
# include <QSignalSpy>
2011-08-17 07:46:54 +00:00
2018-03-08 14:02:45 +00:00
# include <QtQml/QQmlContext>
2012-02-16 04:43:03 +00:00
# include <QtQml/qqmlengine.h>
# include <QtQml/qqmlcomponent.h>
# include <QtQml/qqmlincubator.h>
2017-12-15 12:26:28 +00:00
# include <QtQuick/qquickview.h>
2011-10-14 08:51:42 +00:00
# include <private/qquickloader_p.h>
2017-12-15 12:26:28 +00:00
# include <private/qquickwindowmodule_p.h>
2021-08-06 10:27:35 +00:00
# include <QtQuickTestUtils/private/geometrytestutils_p.h>
# include <QtQuickTestUtils/private/qmlutils_p.h>
# include <QtQuickTestUtils/private/testhttpserver_p.h>
2020-02-12 12:29:08 +00:00
# include <QQmlApplicationEngine>
2011-04-27 12:13:26 +00:00
2017-12-15 12:26:28 +00:00
Q_LOGGING_CATEGORY ( lcTests , " qt.quick.tests " )
2013-03-06 17:47:17 +00:00
class SlowComponent : public QQmlComponent
{
Q_OBJECT
public :
SlowComponent ( ) {
QTest : : qSleep ( 500 ) ;
}
} ;
2011-10-07 06:20:39 +00:00
class PeriodicIncubationController : public QObject ,
2012-02-16 04:43:03 +00:00
public QQmlIncubationController
2011-10-07 06:20:39 +00:00
{
public :
2018-02-21 10:52:59 +00:00
PeriodicIncubationController ( ) { }
2012-07-30 01:10:28 +00:00
void start ( ) { startTimer ( 20 ) ; }
2011-10-07 06:20:39 +00:00
2018-02-21 10:52:59 +00:00
bool incubated = false ;
2012-03-06 08:03:33 +00:00
2011-10-07 06:20:39 +00:00
protected :
2021-03-25 13:44:04 +00:00
void timerEvent ( QTimerEvent * ) override {
2011-10-07 06:20:39 +00:00
incubateFor ( 15 ) ;
}
2012-03-06 08:03:33 +00:00
2021-03-25 13:44:04 +00:00
void incubatingObjectCountChanged ( int count ) override {
2012-03-06 08:03:33 +00:00
if ( count )
incubated = true ;
}
2011-10-07 06:20:39 +00:00
} ;
2012-02-16 04:43:03 +00:00
class tst_QQuickLoader : public QQmlDataTest
2011-04-27 12:13:26 +00:00
{
Q_OBJECT
public :
2011-10-14 08:51:42 +00:00
tst_QQuickLoader ( ) ;
2011-04-27 12:13:26 +00:00
private slots :
void sourceOrComponent ( ) ;
void sourceOrComponent_data ( ) ;
void clear ( ) ;
void urlToComponent ( ) ;
void componentToUrl ( ) ;
void anchoredLoader ( ) ;
void sizeLoaderToItem ( ) ;
void sizeItemToLoader ( ) ;
void noResize ( ) ;
void networkRequestUrl ( ) ;
void failNetworkRequest ( ) ;
2012-03-29 01:14:59 +00:00
void networkComponent ( ) ;
2011-08-17 07:46:54 +00:00
void active ( ) ;
void initialPropertyValues_data ( ) ;
void initialPropertyValues ( ) ;
void initialPropertyValuesBinding ( ) ;
void initialPropertyValuesError_data ( ) ;
void initialPropertyValuesError ( ) ;
2011-04-27 12:13:26 +00:00
void deleteComponentCrash ( ) ;
void nonItem ( ) ;
void vmeErrors ( ) ;
void creationContext ( ) ;
void QTBUG_16928 ( ) ;
void implicitSize ( ) ;
void QTBUG_17114 ( ) ;
2011-10-07 06:20:39 +00:00
void asynchronous_data ( ) ;
void asynchronous ( ) ;
void asynchronous_clear ( ) ;
2012-03-06 08:03:33 +00:00
void simultaneousSyncAsync ( ) ;
2015-09-07 21:29:55 +00:00
void asyncToSync1 ( ) ;
void asyncToSync2 ( ) ;
2012-03-29 01:14:59 +00:00
void loadedSignal ( ) ;
2020-10-30 10:35:00 +00:00
void selfSetSource ( ) ;
2011-04-27 12:13:26 +00:00
2011-11-14 03:00:31 +00:00
void parented ( ) ;
2012-02-16 03:45:02 +00:00
void sizeBound ( ) ;
2013-03-13 17:31:57 +00:00
void QTBUG_30183 ( ) ;
2017-12-15 12:26:28 +00:00
void transientWindow ( ) ;
void nestedTransientWindow ( ) ;
2011-11-14 03:00:31 +00:00
2013-12-05 15:21:03 +00:00
void sourceComponentGarbageCollection ( ) ;
2017-10-24 01:45:00 +00:00
void bindings ( ) ;
void parentErrors ( ) ;
2018-03-08 14:02:45 +00:00
void rootContext ( ) ;
2017-06-02 10:35:07 +00:00
void sourceURLKeepComponent ( ) ;
2020-02-12 12:29:08 +00:00
void statusChangeOnlyEmittedOnce ( ) ;
2020-08-15 06:57:06 +00:00
void setSourceAndCheckStatus ( ) ;
2023-03-06 16:46:38 +00:00
void loadComponentWithStates ( ) ;
2021-09-20 22:10:26 +00:00
void asyncLoaderRace ( ) ;
2022-02-28 14:28:34 +00:00
void noEngine ( ) ;
2022-11-08 07:20:04 +00:00
void stackOverflow ( ) ;
2022-10-10 10:48:49 +00:00
void stackOverflow2 ( ) ;
2022-11-24 12:59:26 +00:00
void boundComponent ( ) ;
2011-04-27 12:13:26 +00:00
} ;
2017-10-24 01:45:00 +00:00
Q_DECLARE_METATYPE ( QList < QQmlError > )
2011-10-14 08:51:42 +00:00
tst_QQuickLoader : : tst_QQuickLoader ( )
2023-03-08 04:24:30 +00:00
: QQmlDataTest ( QT_QMLTEST_DATADIR , FailOnWarningsPolicy : : FailOnWarnings )
2011-04-27 12:13:26 +00:00
{
2013-03-06 17:47:17 +00:00
qmlRegisterType < SlowComponent > ( " LoaderTest " , 1 , 0 , " SlowComponent " ) ;
2017-10-24 01:45:00 +00:00
qRegisterMetaType < QList < QQmlError > > ( ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : sourceOrComponent ( )
2011-04-27 12:13:26 +00:00
{
2011-07-29 04:41:16 +00:00
QFETCH ( QString , sourceOrComponent ) ;
2011-04-27 12:13:26 +00:00
QFETCH ( QString , sourceDefinition ) ;
QFETCH ( QUrl , sourceUrl ) ;
QFETCH ( QString , errorString ) ;
bool error = ! errorString . isEmpty ( ) ;
if ( error )
QTest : : ignoreMessage ( QtWarningMsg , errorString . toUtf8 ( ) . constData ( ) ) ;
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2011-04-27 12:13:26 +00:00
component . setData ( QByteArray (
" import QtQuick 2.0 \n "
" Loader { \n "
" property int onItemChangedCount: 0 \n "
" property int onSourceChangedCount: 0 \n "
2011-07-29 04:41:16 +00:00
" property int onSourceComponentChangedCount: 0 \n "
2011-04-27 12:13:26 +00:00
" property int onStatusChangedCount: 0 \n "
" property int onProgressChangedCount: 0 \n "
" property int onLoadedCount: 0 \n " )
+ sourceDefinition . toUtf8 ( )
+ QByteArray (
" onItemChanged: onItemChangedCount += 1 \n "
" onSourceChanged: onSourceChangedCount += 1 \n "
2011-07-29 04:41:16 +00:00
" onSourceComponentChanged: onSourceComponentChangedCount += 1 \n "
2011-04-27 12:13:26 +00:00
" onStatusChanged: onStatusChangedCount += 1 \n "
" onProgressChanged: onProgressChangedCount += 1 \n "
" onLoaded: onLoadedCount += 1 \n "
" } " )
2011-12-21 08:06:26 +00:00
, dataDirectoryUrl ( ) ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
QCOMPARE ( loader - > item ( ) = = nullptr , error ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > source ( ) , sourceUrl ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , error ? QQuickLoader : : Error : QQuickLoader : : Ready ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , error ? 0 : 1 ) ;
2011-04-27 12:13:26 +00:00
if ( ! error ) {
2011-10-06 04:37:09 +00:00
bool sourceComponentIsChildOfLoader = false ;
for ( int ii = 0 ; ii < loader - > children ( ) . size ( ) ; + + ii ) {
2012-02-16 04:43:03 +00:00
QQmlComponent * c = qobject_cast < QQmlComponent * > ( loader - > children ( ) . at ( ii ) ) ;
2011-10-06 04:37:09 +00:00
if ( c & & c = = loader - > sourceComponent ( ) ) {
sourceComponentIsChildOfLoader = true ;
}
}
QVERIFY ( sourceComponentIsChildOfLoader ) ;
2011-04-27 12:13:26 +00:00
}
2011-07-29 04:41:16 +00:00
if ( sourceOrComponent = = " component " ) {
QCOMPARE ( loader - > property ( " onSourceComponentChangedCount " ) . toInt ( ) , 1 ) ;
QCOMPARE ( loader - > property ( " onSourceChangedCount " ) . toInt ( ) , 0 ) ;
} else {
QCOMPARE ( loader - > property ( " onSourceComponentChangedCount " ) . toInt ( ) , 0 ) ;
QCOMPARE ( loader - > property ( " onSourceChangedCount " ) . toInt ( ) , 1 ) ;
}
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > property ( " onStatusChangedCount " ) . toInt ( ) , 1 ) ;
QCOMPARE ( loader - > property ( " onProgressChangedCount " ) . toInt ( ) , 1 ) ;
2012-06-12 01:47:13 +00:00
QCOMPARE ( loader - > property ( " onItemChangedCount " ) . toInt ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > property ( " onLoadedCount " ) . toInt ( ) , error ? 0 : 1 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : sourceOrComponent_data ( )
2011-04-27 12:13:26 +00:00
{
2011-07-29 04:41:16 +00:00
QTest : : addColumn < QString > ( " sourceOrComponent " ) ;
2011-04-27 12:13:26 +00:00
QTest : : addColumn < QString > ( " sourceDefinition " ) ;
QTest : : addColumn < QUrl > ( " sourceUrl " ) ;
QTest : : addColumn < QString > ( " errorString " ) ;
2020-06-15 15:53:16 +00:00
QTest : : newRow ( " source " ) < < " source " < < " source: 'Rect120x60.qml' \n " < < QUrl ( " Rect120x60.qml " ) < < " " ;
QTest : : newRow ( " source with subdir " ) < < " source " < < " source: 'subdir/Test.qml' \n " < < QUrl ( " subdir/Test.qml " ) < < " " ;
QTest : : newRow ( " source with encoded subdir literal " ) < < " source " < < " source: 'subdir%2fTest.qml' \n " < < QUrl ( " subdir%2FTest.qml " ) < < " " ;
QTest : : newRow ( " source with encoded subdir optimized binding " ) < < " source " < < " source: 'subdir' + '%2fTest.qml' \n " < < QUrl ( " subdir%2FTest.qml " ) < < " " ;
QTest : : newRow ( " source with encoded subdir binding " ) < < " source " < < " source: encodeURIComponent('subdir/Test.qml') \n " < < QUrl ( " subdir%2FTest.qml " ) < < " " ;
2011-07-29 04:41:16 +00:00
QTest : : newRow ( " sourceComponent " ) < < " component " < < " Component { id: comp; Rectangle { width: 100; height: 50 } } \n sourceComponent: comp \n " < < QUrl ( ) < < " " ;
2020-06-15 15:53:16 +00:00
QTest : : newRow ( " invalid source " ) < < " source " < < " source: 'IDontExist.qml' \n " < < QUrl ( " IDontExist.qml " )
2016-06-17 11:21:07 +00:00
< < QString ( testFileUrl ( " IDontExist.qml " ) . toString ( ) + " : No such file or directory " ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : clear ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2011-04-27 12:13:26 +00:00
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2011-04-27 12:13:26 +00:00
component . setData ( QByteArray (
" import QtQuick 2.0 \n "
" Loader { id: loader \n "
" source: 'Rect120x60.qml' \n "
" Timer { interval: 200; running: true; onTriggered: loader.source = '' } \n "
" } " )
2011-12-21 08:06:26 +00:00
, dataDirectoryUrl ( ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QTRY_VERIFY ( ! loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > progress ( ) , 0.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 0 ) ;
2011-04-27 12:13:26 +00:00
}
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /SetSourceComponent.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = qobject_cast < QQuickLoader * > ( item - > QQuickItem : : childItems ( ) . at ( 0 ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
2018-02-21 09:41:54 +00:00
loader - > setSourceComponent ( nullptr ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > progress ( ) , 0.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 0 ) ;
2011-04-27 12:13:26 +00:00
}
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /SetSourceComponent.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = qobject_cast < QQuickLoader * > ( item - > QQuickItem : : childItems ( ) . at ( 0 ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( item . data ( ) , " clear " ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > progress ( ) , 0.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 0 ) ;
2011-04-27 12:13:26 +00:00
}
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : urlToComponent ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2011-04-27 12:13:26 +00:00
component . setData ( QByteArray ( " import QtQuick 2.0 \n "
" Loader { \n "
" id: loader \n "
" Component { id: myComp; Rectangle { width: 10; height: 10 } } \n "
" source: \" Rect120x60.qml \" \n "
" Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp } \n "
" } " )
2011-12-21 08:06:26 +00:00
, dataDirectoryUrl ( ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QTest : : qWait ( 200 ) ;
2018-02-21 09:41:54 +00:00
QTRY_VERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > width ( ) , 10.0 ) ;
QCOMPARE ( loader - > height ( ) , 10.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : componentToUrl ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /SetSourceComponent.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = qobject_cast < QQuickLoader * > ( item - > QQuickItem : : childItems ( ) . at ( 0 ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
2022-07-28 14:09:25 +00:00
loader - > setSourceWithoutResolve ( testFileUrl ( " /Rect120x60.qml " ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > width ( ) , 120.0 ) ;
QCOMPARE ( loader - > height ( ) , 60.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : anchoredLoader ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /AnchoredLoader.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > rootItem ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( rootItem ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickItem * loader = rootItem - > findChild < QQuickItem * > ( " loader " ) ;
QQuickItem * sourceElement = rootItem - > findChild < QQuickItem * > ( " sourceElement " ) ;
2011-04-27 12:13:26 +00:00
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
QVERIFY ( sourceElement ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( rootItem - > width ( ) , 300.0 ) ;
QCOMPARE ( rootItem - > height ( ) , 200.0 ) ;
QCOMPARE ( loader - > width ( ) , 300.0 ) ;
QCOMPARE ( loader - > height ( ) , 200.0 ) ;
QCOMPARE ( sourceElement - > width ( ) , 300.0 ) ;
QCOMPARE ( sourceElement - > height ( ) , 200.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : sizeLoaderToItem ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /SizeToItem.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > width ( ) , 120.0 ) ;
QCOMPARE ( loader - > height ( ) , 60.0 ) ;
// Check resize
2011-10-14 08:51:42 +00:00
QQuickItem * rect = qobject_cast < QQuickItem * > ( loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( rect ) ;
rect - > setWidth ( 150 ) ;
rect - > setHeight ( 45 ) ;
QCOMPARE ( loader - > width ( ) , 150.0 ) ;
QCOMPARE ( loader - > height ( ) , 45.0 ) ;
// Check explicit width
loader - > setWidth ( 200.0 ) ;
QCOMPARE ( loader - > width ( ) , 200.0 ) ;
QCOMPARE ( rect - > width ( ) , 200.0 ) ;
rect - > setWidth ( 100.0 ) ; // when rect changes ...
QCOMPARE ( rect - > width ( ) , 100.0 ) ; // ... it changes
QCOMPARE ( loader - > width ( ) , 200.0 ) ; // ... but loader stays the same
// Check explicit height
loader - > setHeight ( 200.0 ) ;
QCOMPARE ( loader - > height ( ) , 200.0 ) ;
QCOMPARE ( rect - > height ( ) , 200.0 ) ;
rect - > setHeight ( 100.0 ) ; // when rect changes ...
QCOMPARE ( rect - > height ( ) , 100.0 ) ; // ... it changes
QCOMPARE ( loader - > height ( ) , 200.0 ) ; // ... but loader stays the same
// Switch mode
loader - > setWidth ( 180 ) ;
loader - > setHeight ( 30 ) ;
QCOMPARE ( rect - > width ( ) , 180.0 ) ;
QCOMPARE ( rect - > height ( ) , 30.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : sizeItemToLoader ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /SizeToLoader.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > width ( ) , 200.0 ) ;
QCOMPARE ( loader - > height ( ) , 80.0 ) ;
2011-10-14 08:51:42 +00:00
QQuickItem * rect = qobject_cast < QQuickItem * > ( loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( rect ) ;
QCOMPARE ( rect - > width ( ) , 200.0 ) ;
QCOMPARE ( rect - > height ( ) , 80.0 ) ;
// Check resize
2016-06-16 05:40:12 +00:00
QSizeChangeListener sizeListener ( rect ) ;
const QSizeF size ( 180 , 30 ) ;
loader - > setSize ( size ) ;
QVERIFY2 ( ! sizeListener . isEmpty ( ) , " There should be at least one signal about the size changed " ) ;
for ( const QSizeF sizeOnGeometryChanged : sizeListener ) {
// Check that we have the correct size on all signals
QCOMPARE ( sizeOnGeometryChanged , size ) ;
}
QCOMPARE ( rect - > width ( ) , size . width ( ) ) ;
QCOMPARE ( rect - > height ( ) , size . height ( ) ) ;
2011-04-27 12:13:26 +00:00
// Switch mode
loader - > resetWidth ( ) ; // reset explicit size
loader - > resetHeight ( ) ;
rect - > setWidth ( 160 ) ;
rect - > setHeight ( 45 ) ;
QCOMPARE ( loader - > width ( ) , 160.0 ) ;
QCOMPARE ( loader - > height ( ) , 45.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : noResize ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /NoResize.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( item ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( item - > width ( ) , 200.0 ) ;
QCOMPARE ( item - > height ( ) , 80.0 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : networkRequestUrl ( )
2011-04-27 12:13:26 +00:00
{
2015-09-25 08:30:59 +00:00
ThreadedTestHTTPServer server ( dataDirectory ( ) ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2015-04-22 15:15:30 +00:00
const QString qml = " import QtQuick 2.0 \n Loader { property int signalCount : 0; source: \" " + server . baseUrl ( ) . toString ( ) + " /Rect120x60.qml \" ; onLoaded: signalCount += 1 } " ;
component . setData ( qml . toUtf8 ( ) , testFileUrl ( " ../dummy.qml " ) ) ;
2011-04-27 12:13:26 +00:00
if ( component . isError ( ) )
qDebug ( ) < < component . errors ( ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
QCOMPARE ( loader - > property ( " signalCount " ) . toInt ( ) , 1 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
}
2012-03-29 01:14:59 +00:00
/* XXX Component waits until all dependencies are loaded. Is this actually possible? */
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : networkComponent ( )
2011-04-27 12:13:26 +00:00
{
2015-09-25 08:30:59 +00:00
ThreadedTestHTTPServer server ( dataDirectory ( ) , TestHTTPServer : : Delay ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2015-04-22 15:15:30 +00:00
const QString qml = " import QtQuick 2.0 \n "
" import \" " + server . baseUrl ( ) . toString ( ) + " / \" as NW \n "
" Item { \n "
" Component { id: comp; NW.Rect120x60 {} } \n "
" Loader { sourceComponent: comp } } " ;
component . setData ( qml . toUtf8 ( ) , dataDirectory ( ) ) ;
2015-09-25 08:30:59 +00:00
// The component may be loaded synchronously or asynchronously, so we cannot test for
// status == Loading here. Also, it makes no sense to instruct the server to send here
// because in the synchronous case we're already done loading.
2012-12-17 13:00:10 +00:00
QTRY_COMPARE ( component . status ( ) , QQmlComponent : : Ready ) ;
2011-04-27 12:13:26 +00:00
2017-01-19 15:10:09 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
2013-03-06 17:47:17 +00:00
QQuickLoader * loader = qobject_cast < QQuickLoader * > ( item - > children ( ) . at ( 1 ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
2015-07-24 13:32:22 +00:00
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
Port from container::count() and length() to size() - V5
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that on() was replaced with a matcher that doesn't ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Change-Id: I58e1b41b91c34d2e860dbb5847b3752edbfc6fc9
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-10-08 17:56:03 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > children ( ) . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : failNetworkRequest ( )
2011-04-27 12:13:26 +00:00
{
2015-09-25 08:30:59 +00:00
ThreadedTestHTTPServer server ( dataDirectory ( ) ) ;
2011-04-27 12:13:26 +00:00
2015-04-22 15:15:30 +00:00
QTest : : ignoreMessage ( QtWarningMsg , QString ( server . baseUrl ( ) . toString ( ) + " /IDontExist.qml: File not found " ) . toUtf8 ( ) ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine ) ;
2015-04-22 15:15:30 +00:00
const QString qml = " import QtQuick 2.0 \n Loader { property int did_load: 123; source: \" " + server . baseUrl ( ) . toString ( ) + " /IDontExist.qml \" ; onLoaded: did_load=456 } " ;
component . setData ( qml . toUtf8 ( ) , server . url ( " /dummy.qml " ) ) ;
2012-12-17 13:00:10 +00:00
QTRY_COMPARE ( component . status ( ) , QQmlComponent : : Ready ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Error ) ;
2011-04-27 12:13:26 +00:00
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2012-03-06 08:03:33 +00:00
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( loader - > property ( " did_load " ) . toInt ( ) , 123 ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 0 ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : active ( )
2011-08-17 07:46:54 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2011-08-17 07:46:54 +00:00
// check that the item isn't instantiated until active is set to true
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.1.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = false ) ; // set manually to false
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetSourceComponent " ) ;
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetSource " ) ;
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetActive " ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader - > item ( ) ! = nullptr ) ;
2011-08-17 07:46:54 +00:00
}
// check that the status is Null if active is set to false
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.2.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = true ) ; // active is true by default
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2011-08-17 07:46:54 +00:00
int currStatusChangedCount = loader - > property ( " statusChangedCount " ) . toInt ( ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetInactive " ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " statusChangedCount " ) . toInt ( ) , ( currStatusChangedCount + 1 ) ) ;
}
// check that the source is not cleared if active is set to false
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.3.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = true ) ; // active is true by default
QVERIFY ( ! loader - > source ( ) . isEmpty ( ) ) ;
int currSourceChangedCount = loader - > property ( " sourceChangedCount " ) . toInt ( ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetInactive " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( ! loader - > source ( ) . isEmpty ( ) ) ;
QCOMPARE ( loader - > property ( " sourceChangedCount " ) . toInt ( ) , currSourceChangedCount ) ;
}
// check that the sourceComponent is not cleared if active is set to false
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.4.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = true ) ; // active is true by default
2018-02-21 09:41:54 +00:00
QVERIFY ( loader - > sourceComponent ( ) ! = nullptr ) ;
2011-08-17 07:46:54 +00:00
int currSourceComponentChangedCount = loader - > property ( " sourceComponentChangedCount " ) . toInt ( ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetInactive " ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader - > sourceComponent ( ) ! = nullptr ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " sourceComponentChangedCount " ) . toInt ( ) , currSourceComponentChangedCount ) ;
}
// check that the item is released if active is set to false
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.5.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = true ) ; // active is true by default
2018-02-21 09:41:54 +00:00
QVERIFY ( loader - > item ( ) ! = nullptr ) ;
2011-08-17 07:46:54 +00:00
int currItemChangedCount = loader - > property ( " itemChangedCount " ) . toInt ( ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetInactive " ) ;
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " itemChangedCount " ) . toInt ( ) , ( currItemChangedCount + 1 ) ) ;
}
// check that the activeChanged signal is emitted correctly
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.6.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( loader - > active ( ) = = true ) ; // active is true by default
loader - > setActive ( true ) ; // no effect
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 0 ) ;
loader - > setActive ( false ) ; // change signal should be emitted
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 1 ) ;
loader - > setActive ( false ) ; // no effect
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 1 ) ;
loader - > setActive ( true ) ; // change signal should be emitted
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 2 ) ;
loader - > setActive ( false ) ; // change signal should be emitted
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 3 ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetActive " ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 4 ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetActive " ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 4 ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( object . data ( ) , " doSetInactive " ) ;
2011-08-17 07:46:54 +00:00
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 5 ) ;
loader - > setActive ( true ) ; // change signal should be emitted
QCOMPARE ( loader - > property ( " activeChangedCount " ) . toInt ( ) , 6 ) ;
}
2011-10-06 04:37:09 +00:00
// check that the component isn't loaded until active is set to true
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.7.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-06 04:37:09 +00:00
QCOMPARE ( object - > property ( " success " ) . toBool ( ) , true ) ;
}
// check that the component is loaded if active is not set (true by default)
{
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " active.8.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-06 04:37:09 +00:00
QCOMPARE ( object - > property ( " success " ) . toBool ( ) , true ) ;
}
2011-08-17 07:46:54 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : initialPropertyValues_data ( )
2011-08-17 07:46:54 +00:00
{
QTest : : addColumn < QUrl > ( " qmlFile " ) ;
QTest : : addColumn < QStringList > ( " expectedWarnings " ) ;
QTest : : addColumn < QStringList > ( " propertyNames " ) ;
QTest : : addColumn < QVariantList > ( " propertyValues " ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " source url with value set in onLoaded, initially active = true " ) < < testFileUrl ( " initialPropertyValues.1.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " < < " behaviorCount " )
< < ( QVariantList ( ) < < 1 < < 1 ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " set source with initial property values specified, active = true " ) < < testFileUrl ( " initialPropertyValues.2.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " < < " behaviorCount " )
< < ( QVariantList ( ) < < 2 < < 0 ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " set source with initial property values specified, active = false " ) < < testFileUrl ( " initialPropertyValues.3.qml " )
2012-03-14 14:42:58 +00:00
< < ( QStringList ( ) < < QString ( testFileUrl ( " initialPropertyValues.3.qml " ) . toString ( ) + QLatin1String ( " :16: TypeError: Cannot read property 'canary' of null " ) ) )
2011-08-17 07:46:54 +00:00
< < ( QStringList ( ) )
< < ( QVariantList ( ) ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " set source with initial property values specified, active = false, with active set true later " ) < < testFileUrl ( " initialPropertyValues.4.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " < < " behaviorCount " )
< < ( QVariantList ( ) < < 4 < < 0 ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " set source without initial property values specified, active = true " ) < < testFileUrl ( " initialPropertyValues.5.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " < < " behaviorCount " )
< < ( QVariantList ( ) < < 0 < < 0 ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " set source with initial property values specified with binding, active = true " ) < < testFileUrl ( " initialPropertyValues.6.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " < < " behaviorCount " )
< < ( QVariantList ( ) < < 6 < < 0 ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " ensure initial property value semantics mimic createObject " ) < < testFileUrl ( " initialPropertyValues.7.qml " )
2011-08-17 07:46:54 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " loaderValue " < < " createObjectValue " )
< < ( QVariantList ( ) < < 1 < < 1 ) ;
2011-10-06 06:29:52 +00:00
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " ensure initial property values aren't disposed prior to component completion " ) < < testFileUrl ( " initialPropertyValues.8.qml " )
2011-10-06 06:29:52 +00:00
< < QStringList ( )
< < ( QStringList ( ) < < " initialValue " )
< < ( QVariantList ( ) < < 6 ) ;
2019-09-05 11:03:59 +00:00
QTest : : newRow ( " ensure required properties are set correctly " ) < < testFileUrl ( " initialPropertyValues.9.qml " )
< < QStringList ( )
< < ( QStringList ( ) < < " i " < < " s " )
< < ( QVariantList ( ) < < 42 < < QLatin1String ( " hello world " ) ) ;
QTest : : newRow ( " required properties only partially set = " ) < < testFileUrl ( " initialPropertyValues.10.qml " )
< < ( QStringList ( ) < < QString ( testFileUrl ( " RequiredPropertyValuesComponent.qml " ) . toString ( ) + QLatin1String ( " :6:5: Required property s was not initialized " ) ) )
< < ( QStringList ( ) < < " i " < < " s " )
< < ( QVariantList ( ) < < 0 < < QLatin1String ( " " ) ) ;
2019-11-07 06:17:40 +00:00
2019-10-23 08:25:23 +00:00
QTest : : newRow ( " source url changed, previously initial properties are discared " ) < < testFileUrl ( " initialPropertyValues.11.qml " )
< < QStringList ( )
< < ( QStringList ( ) < < " oldi " < < " i " )
< < ( QVariantList ( ) < < 12 < < 42 ) ;
2020-05-04 03:09:13 +00:00
QTest : : newRow ( " ensure initial properties aren't disposed after active = true " ) < < testFileUrl ( " initialPropertyValues.12.qml " )
< < QStringList ( )
< < ( QStringList ( ) < < " i " )
< < ( QVariantList ( ) < < 12 ) ;
2021-01-18 13:32:00 +00:00
QTest : : newRow ( " initial property errors get reported " ) < < testFileUrl ( " initialPropertyTriggerException.qml " )
2022-07-21 13:02:02 +00:00
< < ( QStringList ( ) < < " ^.*:10: Error: Cannot assign JavaScript function to int " )
2021-01-18 13:32:00 +00:00
< < QStringList ( )
< < QVariantList ( ) ;
2011-08-17 07:46:54 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : initialPropertyValues ( )
2011-08-17 07:46:54 +00:00
{
QFETCH ( QUrl , qmlFile ) ;
QFETCH ( QStringList , expectedWarnings ) ;
QFETCH ( QStringList , propertyNames ) ;
QFETCH ( QVariantList , propertyValues ) ;
2015-09-25 08:30:59 +00:00
ThreadedTestHTTPServer server ( dataDirectory ( ) ) ;
2011-10-06 06:29:52 +00:00
2011-08-17 07:46:54 +00:00
foreach ( const QString & warning , expectedWarnings )
2021-01-18 13:32:00 +00:00
QTest : : ignoreMessage ( QtWarningMsg , QRegularExpression ( warning . toLatin1 ( ) . constData ( ) ) ) ;
2011-08-17 07:46:54 +00:00
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , qmlFile ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . beginCreate ( engine . rootContext ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2015-04-22 15:15:30 +00:00
const int serverBaseUrlPropertyIndex = object - > metaObject ( ) - > indexOfProperty ( " serverBaseUrl " ) ;
if ( serverBaseUrlPropertyIndex ! = - 1 ) {
QMetaProperty prop = object - > metaObject ( ) - > property ( serverBaseUrlPropertyIndex ) ;
2017-12-22 10:31:24 +00:00
QVERIFY ( prop . write ( object . data ( ) , server . baseUrl ( ) . toString ( ) ) ) ;
2015-04-22 15:15:30 +00:00
}
component . completeCreate ( ) ;
2012-07-10 03:10:28 +00:00
if ( expectedWarnings . isEmpty ( ) ) {
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
QTRY_VERIFY ( loader - > item ( ) ) ;
}
2011-08-17 07:46:54 +00:00
for ( int i = 0 ; i < propertyNames . size ( ) ; + + i )
2012-05-03 12:42:53 +00:00
QCOMPARE ( object - > property ( propertyNames . at ( i ) . toLatin1 ( ) . constData ( ) ) , propertyValues . at ( i ) ) ;
2011-08-17 07:46:54 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : initialPropertyValuesBinding ( )
2011-08-17 07:46:54 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " initialPropertyValues.binding.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-08-17 07:46:54 +00:00
QVERIFY ( object - > setProperty ( " bindable " , QVariant ( 8 ) ) ) ;
QCOMPARE ( object - > property ( " canaryValue " ) . toInt ( ) , 8 ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : initialPropertyValuesError_data ( )
2011-08-17 07:46:54 +00:00
{
QTest : : addColumn < QUrl > ( " qmlFile " ) ;
QTest : : addColumn < QStringList > ( " expectedWarnings " ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " invalid initial property values object " ) < < testFileUrl ( " initialPropertyValues.error.1.qml " )
< < ( QStringList ( ) < < QString ( testFileUrl ( " initialPropertyValues.error.1.qml " ) . toString ( ) + " :6:5: QML Loader: setSource: value is not an object " ) ) ;
2011-08-17 07:46:54 +00:00
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " nonexistent source url " ) < < testFileUrl ( " initialPropertyValues.error.2.qml " )
2016-06-17 11:21:07 +00:00
< < ( QStringList ( ) < < QString ( testFileUrl ( " NonexistentSourceComponent.qml " ) . toString ( ) + " : No such file or directory " ) ) ;
2011-08-17 07:46:54 +00:00
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " invalid source url " ) < < testFileUrl ( " initialPropertyValues.error.3.qml " )
2018-05-01 16:06:52 +00:00
< < ( QStringList ( ) < < QString ( testFileUrl ( " InvalidSourceComponent.qml " ) . toString ( ) + " :5:1: Expected token `:' " ) ) ;
2011-08-17 07:46:54 +00:00
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " invalid initial property values object with invalid property access " ) < < testFileUrl ( " initialPropertyValues.error.4.qml " )
< < ( QStringList ( ) < < QString ( testFileUrl ( " initialPropertyValues.error.4.qml " ) . toString ( ) + " :7:5: QML Loader: setSource: value is not an object " )
< < QString ( testFileUrl ( " initialPropertyValues.error.4.qml " ) . toString ( ) + " :5: TypeError: Cannot read property 'canary' of null " ) ) ;
2011-08-17 07:46:54 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : initialPropertyValuesError ( )
2011-08-17 07:46:54 +00:00
{
QFETCH ( QUrl , qmlFile ) ;
QFETCH ( QStringList , expectedWarnings ) ;
foreach ( const QString & warning , expectedWarnings )
QTest : : ignoreMessage ( QtWarningMsg , warning . toUtf8 ( ) . constData ( ) ) ;
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , qmlFile ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > object ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( object ! = nullptr ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = object - > findChild < QQuickLoader * > ( " loader " ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-08-17 07:46:54 +00:00
}
2011-04-27 12:13:26 +00:00
// QTBUG-9241
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : deleteComponentCrash ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " crash.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
2017-12-22 10:31:24 +00:00
item - > metaObject ( ) - > invokeMethod ( item . data ( ) , " setLoaderSource " ) ;
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = qobject_cast < QQuickLoader * > ( item - > QQuickItem : : childItems ( ) . at ( 0 ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > item ( ) - > objectName ( ) , QLatin1String ( " blue " ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2018-02-21 09:41:54 +00:00
QCoreApplication : : sendPostedEvents ( nullptr , QEvent : : DeferredDelete ) ;
2012-01-24 00:30:57 +00:00
QCoreApplication : : processEvents ( ) ;
2022-10-05 05:29:16 +00:00
QTRY_COMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2020-06-15 15:53:16 +00:00
QCOMPARE ( loader - > source ( ) , QUrl ( " BlueRect.qml " ) ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : nonItem ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " nonItem.qml " ) ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
2012-06-12 00:16:47 +00:00
QVERIFY ( loader - > item ( ) ) ;
2017-12-22 10:31:24 +00:00
QCOMPARE ( loader . data ( ) , loader - > item ( ) - > parent ( ) ) ;
2012-06-12 00:16:47 +00:00
QPointer < QObject > item = loader - > item ( ) ;
loader - > setActive ( false ) ;
QVERIFY ( ! loader - > item ( ) ) ;
QTRY_VERIFY ( ! item ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : vmeErrors ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " vmeErrors.qml " ) ) ;
2014-02-26 17:43:28 +00:00
QString err = testFileUrl ( " VmeError.qml " ) . toString ( ) + " :6:26: Cannot assign object type QObject with no default method " ;
2011-04-27 12:13:26 +00:00
QTest : : ignoreMessage ( QtWarningMsg , err . toLatin1 ( ) . constData ( ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( loader ) ;
2015-07-24 13:32:22 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-04-27 12:13:26 +00:00
}
// QTBUG-13481
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : creationContext ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " creationContext.qml " ) ) ;
2011-04-27 12:13:26 +00:00
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > o ( component . create ( ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( o ! = nullptr ) ;
2011-04-27 12:13:26 +00:00
QCOMPARE ( o - > property ( " test " ) . toBool ( ) , true ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : QTBUG_16928 ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " QTBUG_16928.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
QCOMPARE ( item - > width ( ) , 250. ) ;
QCOMPARE ( item - > height ( ) , 250. ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : implicitSize ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " implicitSize.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
QCOMPARE ( item - > width ( ) , 150. ) ;
QCOMPARE ( item - > height ( ) , 150. ) ;
QCOMPARE ( item - > property ( " implHeight " ) . toReal ( ) , 100. ) ;
QCOMPARE ( item - > property ( " implWidth " ) . toReal ( ) , 100. ) ;
2012-03-30 00:48:50 +00:00
QQuickLoader * loader = item - > findChild < QQuickLoader * > ( " loader " ) ;
QSignalSpy implWidthSpy ( loader , SIGNAL ( implicitWidthChanged ( ) ) ) ;
QSignalSpy implHeightSpy ( loader , SIGNAL ( implicitHeightChanged ( ) ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( item . data ( ) , " changeImplicitSize " ) ;
2012-03-30 00:48:50 +00:00
QCOMPARE ( loader - > property ( " implicitWidth " ) . toReal ( ) , 200. ) ;
QCOMPARE ( loader - > property ( " implicitHeight " ) . toReal ( ) , 300. ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( implWidthSpy . size ( ) , 1 ) ;
QCOMPARE ( implHeightSpy . size ( ) , 1 ) ;
2011-04-27 12:13:26 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : QTBUG_17114 ( )
2011-04-27 12:13:26 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " QTBUG_17114.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > item ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-04-27 12:13:26 +00:00
QVERIFY ( item ) ;
QCOMPARE ( item - > property ( " loaderWidth " ) . toReal ( ) , 32. ) ;
QCOMPARE ( item - > property ( " loaderHeight " ) . toReal ( ) , 32. ) ;
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : asynchronous_data ( )
2011-10-07 06:20:39 +00:00
{
QTest : : addColumn < QUrl > ( " qmlFile " ) ;
QTest : : addColumn < QStringList > ( " expectedWarnings " ) ;
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " Valid component " ) < < testFileUrl ( " BigComponent.qml " )
2011-10-07 06:20:39 +00:00
< < QStringList ( ) ;
2012-03-06 08:03:33 +00:00
QTest : : newRow ( " Non-existent component " ) < < testFileUrl ( " IDoNotExist.qml " )
2016-06-17 11:21:07 +00:00
< < ( QStringList ( ) < < QString ( testFileUrl ( " IDoNotExist.qml " ) . toString ( ) + " : No such file or directory " ) ) ;
2011-10-07 06:20:39 +00:00
2011-12-21 08:06:26 +00:00
QTest : : newRow ( " Invalid component " ) < < testFileUrl ( " InvalidSourceComponent.qml " )
2018-05-01 16:06:52 +00:00
< < ( QStringList ( ) < < QString ( testFileUrl ( " InvalidSourceComponent.qml " ) . toString ( ) + " :5:1: Expected token `:' " ) ) ;
2011-10-07 06:20:39 +00:00
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : asynchronous ( )
2011-10-07 06:20:39 +00:00
{
QFETCH ( QUrl , qmlFile ) ;
QFETCH ( QStringList , expectedWarnings ) ;
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2012-07-30 01:10:28 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2012-07-30 01:10:28 +00:00
delete previous ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " asynchronous.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( root ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( " loader " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( loader ) ;
foreach ( const QString & warning , expectedWarnings )
QTest : : ignoreMessage ( QtWarningMsg , warning . toUtf8 ( ) . constData ( ) ) ;
QVERIFY ( ! loader - > item ( ) ) ;
2012-03-06 08:03:33 +00:00
QCOMPARE ( loader - > progress ( ) , 0.0 ) ;
2011-10-07 06:20:39 +00:00
root - > setProperty ( " comp " , qmlFile . toString ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
if ( expectedWarnings . isEmpty ( ) ) {
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Loading ) ;
2012-07-30 01:10:28 +00:00
controller - > start ( ) ;
2012-03-06 08:03:33 +00:00
QVERIFY ( ! controller - > incubated ) ; // asynchronous compilation means not immediately compiled/incubating.
QTRY_VERIFY ( controller - > incubated ) ; // but should start incubating once compilation is complete.
2011-10-07 06:20:39 +00:00
QTRY_VERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2011-10-07 06:20:39 +00:00
} else {
2012-03-06 08:03:33 +00:00
QTRY_COMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Error ) ;
2011-10-07 06:20:39 +00:00
}
}
2011-10-14 08:51:42 +00:00
void tst_QQuickLoader : : asynchronous_clear ( )
2011-10-07 06:20:39 +00:00
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2012-07-30 01:10:28 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2012-07-30 01:10:28 +00:00
delete previous ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " asynchronous.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( root ) ;
2011-10-14 08:51:42 +00:00
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( " loader " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( loader ) ;
QVERIFY ( ! loader - > item ( ) ) ;
root - > setProperty ( " comp " , " BigComponent.qml " ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2012-07-30 01:10:28 +00:00
controller - > start ( ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Loading ) ;
2012-03-20 01:58:09 +00:00
QTRY_COMPARE ( engine . incubationController ( ) - > incubatingObjectCount ( ) , 1 ) ;
2011-10-07 06:20:39 +00:00
// clear before component created
root - > setProperty ( " comp " , " " ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
QCOMPARE ( engine . incubationController ( ) - > incubatingObjectCount ( ) , 0 ) ;
QCOMPARE ( loader - > progress ( ) , 0.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 0 ) ;
2011-10-07 06:20:39 +00:00
// check loading component
2012-03-20 01:58:09 +00:00
root - > setProperty ( " comp " , " BigComponent.qml " ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2011-10-07 06:20:39 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Loading ) ;
2011-10-07 06:20:39 +00:00
QCOMPARE ( engine . incubationController ( ) - > incubatingObjectCount ( ) , 1 ) ;
QTRY_VERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
2011-10-14 08:51:42 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2012-03-06 08:03:33 +00:00
}
void tst_QQuickLoader : : simultaneousSyncAsync ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2012-07-30 01:10:28 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2012-07-30 01:10:28 +00:00
delete previous ;
2012-03-06 08:03:33 +00:00
QQmlComponent component ( & engine , testFileUrl ( " simultaneous.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2012-03-06 08:03:33 +00:00
QVERIFY ( root ) ;
QQuickLoader * asyncLoader = root - > findChild < QQuickLoader * > ( " asyncLoader " ) ;
QQuickLoader * syncLoader = root - > findChild < QQuickLoader * > ( " syncLoader " ) ;
QVERIFY ( asyncLoader ) ;
QVERIFY ( syncLoader ) ;
QVERIFY ( ! asyncLoader - > item ( ) ) ;
QVERIFY ( ! syncLoader - > item ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponents " ) ;
2012-03-06 08:03:33 +00:00
QVERIFY ( ! asyncLoader - > item ( ) ) ;
QVERIFY ( syncLoader - > item ( ) ) ;
2012-07-30 01:10:28 +00:00
controller - > start ( ) ;
2012-03-06 08:03:33 +00:00
QCOMPARE ( asyncLoader - > status ( ) , QQuickLoader : : Loading ) ;
QVERIFY ( ! controller - > incubated ) ; // asynchronous compilation means not immediately compiled/incubating.
QTRY_VERIFY ( controller - > incubated ) ; // but should start incubating once compilation is complete.
QTRY_VERIFY ( asyncLoader - > item ( ) ) ;
QCOMPARE ( asyncLoader - > progress ( ) , 1.0 ) ;
QCOMPARE ( asyncLoader - > status ( ) , QQuickLoader : : Ready ) ;
2012-03-29 01:14:59 +00:00
}
2015-09-07 21:29:55 +00:00
void tst_QQuickLoader : : asyncToSync1 ( )
{
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2015-09-07 21:29:55 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2015-09-07 21:29:55 +00:00
delete previous ;
QQmlComponent component ( & engine , testFileUrl ( " asynchronous.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2015-09-07 21:29:55 +00:00
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( " loader " ) ;
QVERIFY ( loader ) ;
QVERIFY ( ! loader - > item ( ) ) ;
root - > setProperty ( " comp " , " BigComponent.qml " ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2015-09-07 21:29:55 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
controller - > start ( ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Loading ) ;
QCOMPARE ( engine . incubationController ( ) - > incubatingObjectCount ( ) , 0 ) ;
// force completion before component created
loader - > setAsynchronous ( false ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2015-09-07 21:29:55 +00:00
}
void tst_QQuickLoader : : asyncToSync2 ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2015-09-07 21:29:55 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2015-09-07 21:29:55 +00:00
delete previous ;
QQmlComponent component ( & engine , testFileUrl ( " asynchronous.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2015-09-07 21:29:55 +00:00
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( " loader " ) ;
QVERIFY ( loader ) ;
QVERIFY ( ! loader - > item ( ) ) ;
root - > setProperty ( " comp " , " BigComponent.qml " ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " loadComponent " ) ;
2015-09-07 21:29:55 +00:00
QVERIFY ( ! loader - > item ( ) ) ;
controller - > start ( ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Loading ) ;
QTRY_COMPARE ( engine . incubationController ( ) - > incubatingObjectCount ( ) , 1 ) ;
// force completion after component created but before incubation complete
loader - > setAsynchronous ( false ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( static_cast < QQuickItem * > ( loader ) - > childItems ( ) . size ( ) , 1 ) ;
2015-09-07 21:29:55 +00:00
}
2012-03-29 01:14:59 +00:00
void tst_QQuickLoader : : loadedSignal ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2022-11-24 13:15:17 +00:00
QScopedPointer < PeriodicIncubationController > controller ( new PeriodicIncubationController ) ;
2013-03-06 17:47:17 +00:00
QQmlIncubationController * previous = engine . incubationController ( ) ;
2022-11-24 13:15:17 +00:00
engine . setIncubationController ( controller . data ( ) ) ;
2013-03-06 17:47:17 +00:00
delete previous ;
2012-03-29 01:14:59 +00:00
{
// ensure that triggering loading (by setting active = true)
// and then immediately setting active to false, causes the
// loader to be deactivated, including disabling the incubator.
QQmlComponent component ( & engine , testFileUrl ( " loadedSignal.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > obj ( component . create ( ) ) ;
2012-03-29 01:14:59 +00:00
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( obj . data ( ) , " triggerLoading " ) ;
2012-03-29 01:14:59 +00:00
QTest : : qWait ( 100 ) ; // ensure that loading would have finished if it wasn't deactivated
QCOMPARE ( obj - > property ( " loadCount " ) . toInt ( ) , 0 ) ;
QVERIFY ( obj - > property ( " success " ) . toBool ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( obj . data ( ) , " triggerLoading " ) ;
2012-03-29 01:14:59 +00:00
QTest : : qWait ( 100 ) ;
QCOMPARE ( obj - > property ( " loadCount " ) . toInt ( ) , 0 ) ;
QVERIFY ( obj - > property ( " success " ) . toBool ( ) ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( obj . data ( ) , " triggerMultipleLoad " ) ;
2013-03-06 17:47:17 +00:00
controller - > start ( ) ;
2012-03-29 01:14:59 +00:00
QTest : : qWait ( 100 ) ;
2013-03-06 17:47:17 +00:00
QTRY_COMPARE ( obj - > property ( " loadCount " ) . toInt ( ) , 1 ) ; // only one loaded signal should be emitted.
2012-03-29 01:14:59 +00:00
QVERIFY ( obj - > property ( " success " ) . toBool ( ) ) ;
}
{
// ensure that an error doesn't result in the onLoaded signal being emitted.
QQmlComponent component ( & engine , testFileUrl ( " loadedSignal.2.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QObject > obj ( component . create ( ) ) ;
2012-03-29 01:14:59 +00:00
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( obj . data ( ) , " triggerLoading " ) ;
2012-03-29 01:14:59 +00:00
QTest : : qWait ( 100 ) ;
QCOMPARE ( obj - > property ( " loadCount " ) . toInt ( ) , 0 ) ;
QVERIFY ( obj - > property ( " success " ) . toBool ( ) ) ;
}
2011-10-07 06:20:39 +00:00
}
2020-10-30 10:35:00 +00:00
void tst_QQuickLoader : : selfSetSource ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine , testFileUrl ( " selfSetSourceTest.qml " ) ) ;
QScopedPointer < QObject > obj ( component . create ( ) ) ;
QVERIFY ( obj ) ;
QTRY_COMPARE ( obj - > property ( " source " ) . toUrl ( ) , testFileUrl ( " empty.qml " ) ) ;
}
2011-11-14 03:00:31 +00:00
void tst_QQuickLoader : : parented ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " parented.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2011-11-14 03:00:31 +00:00
QVERIFY ( root ) ;
QQuickItem * item = root - > findChild < QQuickItem * > ( " comp " ) ;
QVERIFY ( item ) ;
2017-12-22 10:31:24 +00:00
QCOMPARE ( item - > parentItem ( ) , root . data ( ) ) ;
2011-11-14 03:00:31 +00:00
QCOMPARE ( item - > width ( ) , 300. ) ;
QCOMPARE ( item - > height ( ) , 300. ) ;
}
2012-02-16 03:45:02 +00:00
void tst_QQuickLoader : : sizeBound ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2012-02-16 04:43:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " sizebound.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickItem > root ( qobject_cast < QQuickItem * > ( component . create ( ) ) ) ;
2012-02-16 03:45:02 +00:00
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( " loader " ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2012-02-16 03:45:02 +00:00
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( loader - > width ( ) , 50.0 ) ;
QCOMPARE ( loader - > height ( ) , 60.0 ) ;
2017-12-22 10:31:24 +00:00
QMetaObject : : invokeMethod ( root . data ( ) , " switchComponent " ) ;
2012-02-16 03:45:02 +00:00
QCOMPARE ( loader - > width ( ) , 80.0 ) ;
QCOMPARE ( loader - > height ( ) , 90.0 ) ;
}
2013-03-13 17:31:57 +00:00
void tst_QQuickLoader : : QTBUG_30183 ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2013-03-13 17:31:57 +00:00
QQmlComponent component ( & engine , testFileUrl ( " /QTBUG_30183.qml " ) ) ;
2017-12-22 10:31:24 +00:00
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2018-02-21 09:41:54 +00:00
QVERIFY ( loader ! = nullptr ) ;
2013-03-13 17:31:57 +00:00
QCOMPARE ( loader - > width ( ) , 240.0 ) ;
QCOMPARE ( loader - > height ( ) , 120.0 ) ;
// the loaded item must follow the size
QQuickItem * rect = qobject_cast < QQuickItem * > ( loader - > item ( ) ) ;
QVERIFY ( rect ) ;
QCOMPARE ( rect - > width ( ) , 240.0 ) ;
QCOMPARE ( rect - > height ( ) , 120.0 ) ;
}
2011-10-07 06:20:39 +00:00
2017-12-15 12:26:28 +00:00
void tst_QQuickLoader : : transientWindow ( ) // QTBUG-52944
{
QQuickView view ;
view . setSource ( testFileUrl ( " itemLoaderWindow.qml " ) ) ;
QQuickItem * root = qobject_cast < QQuickItem * > ( view . rootObject ( ) ) ;
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( ) ;
QVERIFY ( loader ) ;
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
QQuickWindowQmlImpl * loadedWindow = qobject_cast < QQuickWindowQmlImpl * > ( loader - > item ( ) ) ;
QVERIFY ( loadedWindow ) ;
QCOMPARE ( loadedWindow - > visibility ( ) , QWindow : : Hidden ) ;
QElapsedTimer timer ;
qint64 viewVisibleTime = - 1 ;
qint64 loadedWindowVisibleTime = - 1 ;
connect ( & view , & QWindow : : visibleChanged ,
[ & viewVisibleTime , & timer ] ( ) { viewVisibleTime = timer . elapsed ( ) ; } ) ;
connect ( loadedWindow , & QQuickWindowQmlImpl : : visibilityChanged ,
[ & loadedWindowVisibleTime , & timer ] ( ) { loadedWindowVisibleTime = timer . elapsed ( ) ; } ) ;
timer . start ( ) ;
view . show ( ) ;
2018-02-21 08:16:14 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2017-12-15 12:26:28 +00:00
QTRY_VERIFY ( loadedWindowVisibleTime > = 0 ) ;
QVERIFY ( viewVisibleTime > = 0 ) ;
// now that we're sure they are both visible, which one became visible first?
qCDebug ( lcTests ) < < " transient Window became visible " < < ( loadedWindowVisibleTime - viewVisibleTime ) < < " ms after the root Item " ;
QVERIFY ( ( loadedWindowVisibleTime - viewVisibleTime ) > = 0 ) ;
QWindowList windows = QGuiApplication : : topLevelWindows ( ) ;
QTRY_COMPARE ( windows . size ( ) , 2 ) ;
// TODO Ideally we would now close the outer window and make sure the transient window closes too.
// It works during manual testing because of QWindowPrivate::maybeQuitOnLastWindowClosed()
// but quitting an autotest doesn't make sense.
}
void tst_QQuickLoader : : nestedTransientWindow ( ) // QTBUG-52944
{
QQuickView view ;
view . setSource ( testFileUrl ( " itemLoaderItemWindow.qml " ) ) ;
QQuickItem * root = qobject_cast < QQuickItem * > ( view . rootObject ( ) ) ;
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( ) ;
QVERIFY ( loader ) ;
QTRY_COMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
QQuickItem * loadedItem = qobject_cast < QQuickItem * > ( loader - > item ( ) ) ;
QVERIFY ( loadedItem ) ;
QQuickWindowQmlImpl * loadedWindow = loadedItem - > findChild < QQuickWindowQmlImpl * > ( ) ;
QVERIFY ( loadedWindow ) ;
QCOMPARE ( loadedWindow - > visibility ( ) , QWindow : : Hidden ) ;
QElapsedTimer timer ;
qint64 viewVisibleTime = - 1 ;
qint64 loadedWindowVisibleTime = - 1 ;
connect ( & view , & QWindow : : visibleChanged ,
[ & viewVisibleTime , & timer ] ( ) { viewVisibleTime = timer . elapsed ( ) ; } ) ;
connect ( loadedWindow , & QQuickWindowQmlImpl : : visibilityChanged ,
[ & loadedWindowVisibleTime , & timer ] ( ) { loadedWindowVisibleTime = timer . elapsed ( ) ; } ) ;
timer . start ( ) ;
view . show ( ) ;
2018-02-21 08:16:14 +00:00
QVERIFY ( QTest : : qWaitForWindowExposed ( & view ) ) ;
2017-12-15 12:26:28 +00:00
QTRY_VERIFY ( loadedWindowVisibleTime > = 0 ) ;
QVERIFY ( viewVisibleTime > = 0 ) ;
// now that we're sure they are both visible, which one became visible first?
qCDebug ( lcTests ) < < " transient Window became visible " < < ( loadedWindowVisibleTime - viewVisibleTime ) < < " ms after the root Item " ;
QVERIFY ( ( loadedWindowVisibleTime - viewVisibleTime ) > = 0 ) ;
QWindowList windows = QGuiApplication : : topLevelWindows ( ) ;
QTRY_COMPARE ( windows . size ( ) , 2 ) ;
// TODO Ideally we would now close the outer window and make sure the transient window closes too.
// It works during manual testing because of QWindowPrivate::maybeQuitOnLastWindowClosed()
// but quitting an autotest doesn't make sense.
}
2013-12-05 15:21:03 +00:00
void tst_QQuickLoader : : sourceComponentGarbageCollection ( )
{
2017-12-22 10:06:13 +00:00
QQmlEngine engine ;
2013-12-05 15:21:03 +00:00
QQmlComponent component ( & engine , testFileUrl ( " sourceComponentGarbageCollection.qml " ) ) ;
QScopedPointer < QObject > obj ( component . create ( ) ) ;
QVERIFY ( ! obj . isNull ( ) ) ;
QMetaObject : : invokeMethod ( obj . data ( ) , " setSourceComponent " ) ;
engine . collectGarbage ( ) ;
2018-02-21 09:41:54 +00:00
QCoreApplication : : sendPostedEvents ( nullptr , QEvent : : DeferredDelete ) ;
2013-12-05 15:21:03 +00:00
QSignalSpy spy ( obj . data ( ) , SIGNAL ( loaded ( ) ) ) ;
obj - > setProperty ( " active " , true ) ;
if ( spy . isEmpty ( ) )
QVERIFY ( spy . wait ( ) ) ;
2022-10-05 05:29:16 +00:00
QCOMPARE ( spy . size ( ) , 1 ) ;
2013-12-05 15:21:03 +00:00
}
2017-10-24 01:45:00 +00:00
// QTBUG-51995
void tst_QQuickLoader : : bindings ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine , testFileUrl ( " bindings.qml " ) ) ;
QScopedPointer < QObject > object ( component . create ( ) ) ;
QVERIFY ( ! object . isNull ( ) ) ;
QQuickItem * game = object - > property ( " game " ) . value < QQuickItem * > ( ) ;
QVERIFY ( game ) ;
QQuickLoader * loader = object - > property ( " loader " ) . value < QQuickLoader * > ( ) ;
QVERIFY ( loader ) ;
QSignalSpy warningsSpy ( & engine , SIGNAL ( warnings ( QList < QQmlError > ) ) ) ;
// Causes the Loader to become active
game - > setState ( QLatin1String ( " running " ) ) ;
QTRY_VERIFY ( loader - > item ( ) ) ;
// Causes the Loader to become inactive - should not cause binding errors
game - > setState ( QLatin1String ( " invalid " ) ) ;
QTRY_VERIFY ( ! loader - > item ( ) ) ;
QString failureMessage ;
if ( ! warningsSpy . isEmpty ( ) ) {
QDebug stream ( & failureMessage ) ;
stream < < warningsSpy . first ( ) . first ( ) . value < QList < QQmlError > > ( ) ;
}
QVERIFY2 ( warningsSpy . isEmpty ( ) , qPrintable ( failureMessage ) ) ;
}
// QTBUG-47321
void tst_QQuickLoader : : parentErrors ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine , testFileUrl ( " parentErrors.qml " ) ) ;
QScopedPointer < QObject > object ( component . create ( ) ) ;
QVERIFY ( ! object . isNull ( ) ) ;
QQuickLoader * loader = object - > property ( " loader " ) . value < QQuickLoader * > ( ) ;
QVERIFY ( loader ) ;
QSignalSpy warningsSpy ( & engine , SIGNAL ( warnings ( QList < QQmlError > ) ) ) ;
// Give the loader a component
loader - > setSourceComponent ( object - > property ( " component " ) . value < QQmlComponent * > ( ) ) ;
QTRY_VERIFY ( loader - > item ( ) ) ;
// Clear the loader's component; should not cause binding errors
loader - > setSourceComponent ( nullptr ) ;
QTRY_VERIFY ( ! loader - > item ( ) ) ;
QString failureMessage ;
if ( ! warningsSpy . isEmpty ( ) ) {
QDebug stream ( & failureMessage ) ;
stream < < warningsSpy . first ( ) . first ( ) . value < QList < QQmlError > > ( ) ;
}
QVERIFY2 ( warningsSpy . isEmpty ( ) , qPrintable ( failureMessage ) ) ;
}
2018-03-08 14:02:45 +00:00
class ObjectInRootContext : public QObject
{
Q_OBJECT
public :
int didIt = 0 ;
public slots :
void doIt ( ) {
didIt + = 1 ;
}
} ;
void tst_QQuickLoader : : rootContext ( )
{
QQmlEngine engine ;
ObjectInRootContext objectInRootContext ;
engine . rootContext ( ) - > setContextProperty ( " objectInRootContext " , & objectInRootContext ) ;
QQmlComponent component ( & engine , testFileUrl ( " rootContext.qml " ) ) ;
QScopedPointer < QObject > object ( component . create ( ) ) ;
QVERIFY ( ! object . isNull ( ) ) ;
QQuickLoader * loader = object - > property ( " loader " ) . value < QQuickLoader * > ( ) ;
QVERIFY ( loader ) ;
QSignalSpy warningsSpy ( & engine , SIGNAL ( warnings ( QList < QQmlError > ) ) ) ;
// Give the loader a component
loader - > setSourceComponent ( object - > property ( " component " ) . value < QQmlComponent * > ( ) ) ;
QTRY_VERIFY ( loader - > active ( ) ) ;
QTRY_VERIFY ( loader - > item ( ) ) ;
QString failureMessage ;
if ( ! warningsSpy . isEmpty ( ) ) {
QDebug stream ( & failureMessage ) ;
stream < < warningsSpy . first ( ) . first ( ) . value < QList < QQmlError > > ( ) ;
}
QVERIFY2 ( warningsSpy . isEmpty ( ) , qPrintable ( failureMessage ) ) ;
QCOMPARE ( objectInRootContext . didIt , 0 ) ;
// Deactivate the loader, which deletes the item.
// Check that a) there are no errors, and b) the objectInRootContext can still be resolved even
// after deactivating the loader. If it cannot, a ReferenceError for objectInRootContext is
// generated (and the 'doIt' counter in objectInRootContext will be 1 for the call before
// the deactivation).
loader - > item ( ) - > setProperty ( " trigger " , true ) ;
QTRY_VERIFY ( ! loader - > active ( ) ) ;
QTRY_VERIFY ( ! loader - > item ( ) ) ;
if ( ! warningsSpy . isEmpty ( ) ) {
QDebug stream ( & failureMessage ) ;
stream < < warningsSpy . first ( ) . first ( ) . value < QList < QQmlError > > ( ) ;
}
QVERIFY2 ( warningsSpy . isEmpty ( ) , qPrintable ( failureMessage ) ) ;
QCOMPARE ( objectInRootContext . didIt , 2 ) ;
}
2017-06-02 10:35:07 +00:00
void tst_QQuickLoader : : sourceURLKeepComponent ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine ) ;
component . setData ( QByteArray (
" import QtQuick 2.0 \n "
" Loader { id: loader \n } " ) ,
dataDirectoryUrl ( ) ) ;
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
2022-07-28 14:09:25 +00:00
loader - > setSourceWithoutResolve ( testFileUrl ( " /Rect120x60.qml " ) ) ;
2017-06-02 10:35:07 +00:00
QVERIFY ( loader ) ;
QVERIFY ( loader - > item ( ) ) ;
QVERIFY ( loader - > sourceComponent ( ) ) ;
QCOMPARE ( loader - > progress ( ) , 1.0 ) ;
const QPointer < QQmlComponent > sourceComponent = loader - > sourceComponent ( ) ;
//Ensure toggling active status does not recreate component
loader - > setActive ( false ) ;
QVERIFY ( ! loader - > item ( ) ) ;
QVERIFY ( loader - > sourceComponent ( ) ) ;
QCOMPARE ( sourceComponent . data ( ) , loader - > sourceComponent ( ) ) ;
loader - > setActive ( true ) ;
QVERIFY ( loader - > item ( ) ) ;
QVERIFY ( loader - > sourceComponent ( ) ) ;
QCOMPARE ( sourceComponent . data ( ) , loader - > sourceComponent ( ) ) ;
loader - > setActive ( false ) ;
QVERIFY ( ! loader - > item ( ) ) ;
QVERIFY ( loader - > sourceComponent ( ) ) ;
QCOMPARE ( sourceComponent . data ( ) , loader - > sourceComponent ( ) ) ;
//Ensure changing source url causes component to be recreated when inactive
2022-07-28 14:09:25 +00:00
loader - > setSourceWithoutResolve ( testFileUrl ( " /BlueRect.qml " ) ) ;
2017-06-02 10:35:07 +00:00
loader - > setActive ( true ) ;
QVERIFY ( loader - > item ( ) ) ;
QVERIFY ( loader - > sourceComponent ( ) ) ;
const QPointer < QQmlComponent > newSourceComponent = loader - > sourceComponent ( ) ;
QVERIFY ( sourceComponent . data ( ) ! = newSourceComponent . data ( ) ) ;
//Ensure changing source url causes component to be recreated when active
2022-07-28 14:09:25 +00:00
loader - > setSourceWithoutResolve ( testFileUrl ( " /Rect120x60.qml " ) ) ;
2017-06-02 10:35:07 +00:00
QVERIFY ( loader - > sourceComponent ( ) ! = newSourceComponent . data ( ) ) ;
}
2020-02-12 12:29:08 +00:00
// QTBUG-82002
void tst_QQuickLoader : : statusChangeOnlyEmittedOnce ( )
{
QQmlApplicationEngine engine ;
auto url = testFileUrl ( " statusChanged.qml " ) ;
engine . load ( url ) ;
auto root = engine . rootObjects ( ) . at ( 0 ) ;
QVERIFY ( root ) ;
QTRY_COMPARE ( QQuickLoader : : Status ( root - > property ( " status " ) . toInt ( ) ) , QQuickLoader : : Ready ) ;
QCOMPARE ( root - > property ( " statusChangedCounter " ) . toInt ( ) , 2 ) ; // 1xLoading + 1xReady*/
}
2020-08-15 06:57:06 +00:00
void tst_QQuickLoader : : setSourceAndCheckStatus ( )
{
QQmlApplicationEngine engine ;
auto url = testFileUrl ( " setSourceAndCheckStatus.qml " ) ;
engine . load ( url ) ;
auto root = engine . rootObjects ( ) . at ( 0 ) ;
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( ) ;
QMetaObject : : invokeMethod ( loader , " load " , Q_ARG ( QVariant , QVariant : : fromValue ( QStringLiteral ( " ./RedRect.qml " ) ) ) ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Ready ) ;
QMetaObject : : invokeMethod ( loader , " load " , Q_ARG ( QVariant , QVariant : : fromValue ( QStringLiteral ( " " ) ) ) ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2020-08-15 07:26:51 +00:00
2023-03-08 04:24:30 +00:00
QMetaObject : : invokeMethod ( loader , " load " , Q_ARG ( QVariant , QVariant ( QUrl ( ) ) ) ) ;
2020-08-15 07:26:51 +00:00
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
2020-08-15 06:57:06 +00:00
}
2023-03-06 16:46:38 +00:00
void tst_QQuickLoader : : loadComponentWithStates ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine ) ;
component . setData ( QByteArray ( " import QtQuick \n "
" Loader { \n "
" id: loader \n "
" property int createdObjCount: 0 \n "
" states: [ State { when: true; PropertyChanges { target: loader; sourceComponent: myComp } } ] \n "
" Component { id: myComp; Item { Component.onCompleted: { ++createdObjCount } } } \n "
" } " )
, dataDirectoryUrl ( ) ) ;
QScopedPointer < QQuickLoader > loader ( qobject_cast < QQuickLoader * > ( component . create ( ) ) ) ;
QTest : : qWait ( 200 ) ;
QTRY_VERIFY ( loader ! = nullptr ) ;
QVERIFY ( loader - > item ( ) ) ;
QCOMPARE ( static_cast < QQuickItem * > ( loader . data ( ) ) - > childItems ( ) . size ( ) , 1 ) ;
QCOMPARE ( loader - > property ( " createdObjCount " ) . toInt ( ) , 1 ) ;
}
2021-09-20 22:10:26 +00:00
void tst_QQuickLoader : : asyncLoaderRace ( )
{
QQmlApplicationEngine engine ;
auto url = testFileUrl ( " loader-async-race.qml " ) ;
engine . load ( url ) ;
auto root = engine . rootObjects ( ) . at ( 0 ) ;
QVERIFY ( root ) ;
QQuickLoader * loader = root - > findChild < QQuickLoader * > ( ) ;
QCOMPARE ( loader - > active ( ) , false ) ;
QCOMPARE ( loader - > status ( ) , QQuickLoader : : Null ) ;
QCOMPARE ( loader - > item ( ) , nullptr ) ;
QSignalSpy spy ( loader , & QQuickLoader : : itemChanged ) ;
QVERIFY ( ! spy . wait ( 100 ) ) ;
QCOMPARE ( loader - > item ( ) , nullptr ) ;
}
2022-02-28 14:28:34 +00:00
void tst_QQuickLoader : : noEngine ( )
{
QQmlEngine engine ;
const QUrl url = testFileUrl ( " noEngine.qml " ) ;
QQmlComponent component ( & engine , url ) ;
QVERIFY2 ( component . isReady ( ) , qPrintable ( component . errorString ( ) ) ) ;
QScopedPointer < QObject > o ( component . create ( ) ) ;
const QString message = url . toString ( )
+ QStringLiteral ( " :27:13: QML Loader: createComponent: Cannot find a QML engine. " ) ;
QTest : : ignoreMessage ( QtWarningMsg , qPrintable ( message ) ) ;
QTRY_COMPARE ( o - > property ( " changes " ) . toInt ( ) , 1 ) ;
}
2022-10-10 10:48:49 +00:00
static void qTestForOverflow ( const QUrl & url )
2022-11-08 07:20:04 +00:00
{
QQmlEngine engine ;
QQmlComponent component ( & engine , url ) ;
QVERIFY2 ( component . isReady ( ) , qPrintable ( component . errorString ( ) ) ) ;
const QString message = url . toString ( ) + QStringLiteral ( " : Maximum call stack size exceeded. " ) ;
QTest : : ignoreMessage ( QtCriticalMsg , qPrintable ( message ) ) ;
QScopedPointer < QObject > o ( component . create ( ) ) ;
}
2022-10-10 10:48:49 +00:00
void tst_QQuickLoader : : stackOverflow ( )
{
auto t = QThread : : create ( qTestForOverflow , testFileUrl ( " overflow.qml " ) ) ;
t - > setStackSize ( 1024 * 1024 ) ;
t - > start ( ) ;
t - > wait ( ) ;
}
void tst_QQuickLoader : : stackOverflow2 ( )
{
auto t = QThread : : create ( qTestForOverflow , testFileUrl ( " overflow2.qml " ) ) ;
t - > setStackSize ( 1024 * 1024 ) ;
t - > start ( ) ;
t - > wait ( ) ;
}
2022-11-24 12:59:26 +00:00
void tst_QQuickLoader : : boundComponent ( )
{
QQmlEngine engine ;
QQmlComponent component ( & engine , testFileUrl ( " boundComponent.qml " ) ) ;
QVERIFY2 ( component . isReady ( ) , qPrintable ( component . errorString ( ) ) ) ;
QScopedPointer < QObject > o ( component . create ( ) ) ;
QCOMPARE ( o - > objectName ( ) , QStringLiteral ( " loaded " ) ) ;
}
2011-10-14 08:51:42 +00:00
QTEST_MAIN ( tst_QQuickLoader )
2011-04-27 12:13:26 +00:00
2011-10-14 08:51:42 +00:00
# include "tst_qquickloader.moc"