aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-24 01:00:21 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-10-24 01:00:21 +0200
commit2ebbf03e880467ecc95adfafe7c0404add8a3328 (patch)
tree3cce73a83a3b6cb1dd3cefd936a915b333d1fd65
parent33bfa05c59a0d4ebcc8943ff710ee1da207da014 (diff)
parent8a2c182d5941a1d00ac9f7414d1508b7f959d6f3 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp14
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp29
-rw-r--r--src/quick/util/qquickstategroup.cpp8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables.mjs31
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.mjs8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.qml10
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.js9
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.qml10
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.js8
-rw-r--r--tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.qml10
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp34
-rw-r--r--tests/auto/qml/qqmllanguage/data/polymorphicFunctionLookup.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h2
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp13
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp2
19 files changed, 202 insertions, 24 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 883b21ab07..9021fd0284 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1947,11 +1947,7 @@ QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache
{
QQmlPropertyData *pd = cache->property(name, /*object*/nullptr, /*context*/nullptr);
- // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
- if (!pd || pd->isFunction())
- return nullptr;
-
- if (!cache->isAllowedInRevision(pd))
+ if (pd && !cache->isAllowedInRevision(pd))
return nullptr;
return pd;
@@ -2280,6 +2276,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
if (_scopeObject) {
QQmlPropertyData *data = lookupQmlCompliantProperty(_scopeObject, name);
if (data) {
+ // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
+ if (data->isFunction())
+ return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
Reference::PropertyCapturePolicy capturePolicy;
if (!data->isConstant() && !data->isQmlBinding())
@@ -2293,6 +2293,10 @@ QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &n
if (_contextObject) {
QQmlPropertyData *data = lookupQmlCompliantProperty(_contextObject, name);
if (data) {
+ // Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
+ if (data->isFunction())
+ return Reference::fromName(this, name);
+
Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
Reference::PropertyCapturePolicy capturePolicy;
if (!data->isConstant() && !data->isQmlBinding())
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 2e4223de7d..8cdec2f6ee 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -764,11 +764,11 @@ struct QObjectWrapperOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
{
int propertyIndex = 0;
~QObjectWrapperOwnPropertyKeyIterator() override = default;
- PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
};
-PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
+PropertyKey QObjectWrapperOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
// Used to block access to QObject::destroyed() and QObject::deleteLater() from QML
static const int destroyedIdx1 = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 634fbcbd97..4ef4fa2c9e 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -238,20 +238,20 @@ void Heap::RegExpCtor::clearLastMatch()
lastMatchEnd = 0;
}
-static bool isRegExp(ExecutionEngine *e, const Value *arg)
+static bool isRegExp(ExecutionEngine *e, const QV4::Value *arg)
{
- const Object *o = arg->objectValue();
+ const QV4::Object *o = arg->objectValue();
if (!o)
return false;
- Value isRegExp = Value::fromReturnedValue(o->get(e->symbol_match()));
+ QV4::Value isRegExp = QV4::Value::fromReturnedValue(o->get(e->symbol_match()));
if (!isRegExp.isUndefined())
return isRegExp.toBoolean();
const RegExpObject *re = o->as<RegExpObject>();
return re ? true : false;
}
-uint parseFlags(Scope &scope, const Value *f)
+uint parseFlags(Scope &scope, const QV4::Value *f)
{
uint flags = CompiledData::RegExp::RegExp_NoFlags;
if (!f->isUndefined()) {
@@ -546,13 +546,13 @@ static int advanceStringIndex(int index, const QString &str, bool unicode)
return index;
}
-static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, Object *rx, const String *matchString, const QString &str)
+static void advanceLastIndexOnEmptyMatch(ExecutionEngine *e, bool unicode, QV4::Object *rx, const String *matchString, const QString &str)
{
Scope scope(e);
if (matchString->d()->length() == 0) {
- ScopedValue v(scope, rx->get(scope.engine->id_lastIndex()));
+ QV4::ScopedValue v(scope, rx->get(scope.engine->id_lastIndex()));
int lastIndex = advanceStringIndex(v->toLength(), str, unicode);
- if (!rx->put(scope.engine->id_lastIndex(), Value::fromInt32(lastIndex)))
+ if (!rx->put(scope.engine->id_lastIndex(), QV4::Value::fromInt32(lastIndex)))
scope.engine->throwTypeError();
}
}
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index f6b9c5ba94..03f351b9e4 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -112,11 +112,11 @@ bool StringObject::virtualDeleteProperty(Managed *m, PropertyKey id)
struct StringObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator
{
~StringObjectOwnPropertyKeyIterator() override = default;
- PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
+ PropertyKey next(const QV4::Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override;
};
-PropertyKey StringObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs)
+PropertyKey StringObjectOwnPropertyKeyIterator::next(const QV4::Object *o, Property *pd, PropertyAttributes *attrs)
{
const StringObject *s = static_cast<const StringObject *>(o);
uint slen = s->d()->string->toQString().length();
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 29814246db..1cca50f6c1 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -377,7 +377,7 @@ static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs)
if (lhs.m()->internalClass->vtable->isString)
return RuntimeHelpers::stringToNumber(static_cast<String &>(lhs).toQString()) == rhs;
accumulator = lhs;
- lhs = Value::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
+ lhs = QV4::Value::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
goto redo;
case QV4::Value::QT_Empty:
Q_UNREACHABLE();
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index ea4a69f05d..ba8d5831ad 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -847,21 +847,40 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
}
}
+ QSet<QString> localEnums;
+ const QMetaObject *localMetaObject = nullptr;
+
// Add any enum values defined by this class, overwriting any inherited values
for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
QMetaEnum e = metaObject->enumerator(ii);
const bool isScoped = e.isScoped();
QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : nullptr;
+ // We allow enums in sub-classes to overwrite enums from base-classes, such as
+ // ListView.Center (from enum PositionMode) overwriting Item.Center (from enum TransformOrigin).
+ // This is acceptable because the _use_ of the enum from the QML side requires qualification
+ // anyway, i.e. ListView.Center vs. Item.Center.
+ // However if a class defines two enums with the same value, then that must produce a warning
+ // because it represents a valid conflict.
+ if (e.enclosingMetaObject() != localMetaObject) {
+ localEnums.clear();
+ localMetaObject = e.enclosingMetaObject();
+ }
+
for (int jj = 0; jj < e.keyCount(); ++jj) {
const QString key = QString::fromUtf8(e.key(jj));
const int value = e.value(jj);
if (!isScoped || (regType == QQmlType::CppType && extraData.cd->registerEnumClassesUnscoped)) {
- if (enums.contains(key)) {
- qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData());
- createEnumConflictReport(metaObject, key);
- }
- enums.insert(key, value);
+ if (localEnums.contains(key)) {
+ auto existingEntry = enums.find(key);
+ if (existingEntry != enums.end() && existingEntry.value() != value) {
+ qWarning("Previously registered enum will be overwritten due to name clash: %s.%s", metaObject->className(), key.toUtf8().constData());
+ createEnumConflictReport(metaObject, key);
+ }
+ } else {
+ localEnums.insert(key);
+ }
+ enums.insert(key, value);
}
if (isScoped)
scoped->insert(key, value);
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index c852c16509..3d8c5e0507 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -302,10 +302,18 @@ void QQuickStateGroup::componentComplete()
Q_D(QQuickStateGroup);
d->componentComplete = true;
+ QSet<QString> names;
for (int ii = 0; ii < d->states.count(); ++ii) {
QQuickState *state = d->states.at(ii);
if (!state->isNamed())
state->setName(QLatin1String("anonymousState") + QString::number(++d->unnamedCount));
+
+ const QString stateName = state->name();
+ if (names.contains(stateName)) {
+ qmlWarning(state->parent()) << "Found duplicate state name: " << stateName;
+ } else {
+ names << stateName;
+ }
}
if (d->updateAutoState()) {
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables.mjs b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables.mjs
new file mode 100644
index 0000000000..19c012d19b
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables.mjs
@@ -0,0 +1,31 @@
+export function runTest(libraryUnderTest) {
+ let state1 = state(libraryUnderTest);
+ try { modifyFromOutside(libraryUnderTest); } catch (e) {}
+ let state2 = state(libraryUnderTest);
+ try { modifyFromInside(libraryUnderTest); } catch (e) {}
+ let state3 = state(libraryUnderTest);
+ return state1 + " " + state2 + " " + state3;
+}
+
+function stringify(value) {
+ let s = "?";
+ if (value !== undefined)
+ s = value.toString();
+ return s;
+}
+
+function state(libraryUnderTest) {
+ return (stringify(libraryUnderTest.varValue) +
+ stringify(libraryUnderTest.letValue) +
+ stringify(libraryUnderTest.constValue));
+}
+
+function modifyFromOutside(libraryUnderTest) {
+ ++libraryUnderTest.varValue;
+ ++libraryUnderTest.letValue;
+ ++libraryUnderTest.constValue;
+}
+
+function modifyFromInside(libraryUnderTest) {
+ libraryUnderTest.incrementAll();
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.mjs b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.mjs
new file mode 100644
index 0000000000..b6eb1a2623
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.mjs
@@ -0,0 +1,8 @@
+export var varValue = 0;
+export let letValue = 0;
+export const constValue = 0;
+export function incrementAll() {
+ ++varValue;
+ ++letValue;
+ ++constValue;
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.qml b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.qml
new file mode 100644
index 0000000000..bb4e759cbf
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_module.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import "importLexicalVariables.mjs" as TestRunner
+import "importLexicalVariables_module.mjs" as LibraryUnderTest
+
+QtObject {
+ id: root
+ function runTest() {
+ return TestRunner.runTest(LibraryUnderTest);
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.js b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.js
new file mode 100644
index 0000000000..f8c215a5e7
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.js
@@ -0,0 +1,9 @@
+.pragma library
+var varValue = 0;
+let letValue = 0;
+const constValue = 0;
+function incrementAll() {
+ ++varValue;
+ ++letValue;
+ ++constValue;
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.qml b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.qml
new file mode 100644
index 0000000000..1b3fe7fa2e
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_pragmaLibrary.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import "importLexicalVariables.mjs" as TestRunner
+import "importLexicalVariables_pragmaLibrary.js" as LibraryUnderTest
+
+QtObject {
+ id: root
+ function runTest() {
+ return TestRunner.runTest(LibraryUnderTest);
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.js b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.js
new file mode 100644
index 0000000000..4fb68abc87
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.js
@@ -0,0 +1,8 @@
+var varValue = 0;
+let letValue = 0;
+const constValue = 0;
+function incrementAll() {
+ ++varValue;
+ ++letValue;
+ ++constValue;
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.qml b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.qml
new file mode 100644
index 0000000000..263511e802
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/importLexicalVariables_script.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import "importLexicalVariables.mjs" as TestRunner
+import "importLexicalVariables_script.js" as LibraryUnderTest
+
+QtObject {
+ id: root
+ function runTest() {
+ return TestRunner.runTest(LibraryUnderTest);
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index cf3eecff6d..8f388fcac6 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -357,6 +357,8 @@ private slots:
void jumpStrictNotEqualUndefined();
void removeBindingsWithNoDependencies();
void temporaryDeadZone();
+ void importLexicalVariables_data();
+ void importLexicalVariables();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -8812,6 +8814,38 @@ void tst_qqmlecmascript::temporaryDeadZone()
QVERIFY(v.isError());
}
+void tst_qqmlecmascript::importLexicalVariables_data()
+{
+ QTest::addColumn<QUrl>("testFile");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("script")
+ << testFileUrl("importLexicalVariables_script.qml")
+ << QStringLiteral("0?? 1?? 2??");
+ QTest::newRow("pragmaLibrary")
+ << testFileUrl("importLexicalVariables_pragmaLibrary.qml")
+ << QStringLiteral("0?? 1?? 2??");
+ QTest::newRow("module")
+ << testFileUrl("importLexicalVariables_module.qml")
+ << QStringLiteral("000 000 110");
+}
+
+void tst_qqmlecmascript::importLexicalVariables()
+{
+ QFETCH(QUrl, testFile);
+ QFETCH(QString, expected);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFile);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object != nullptr);
+ QVERIFY(!component.isError());
+
+ QVariant result;
+ QMetaObject::invokeMethod(object.data(), "runTest", Qt::DirectConnection, Q_RETURN_ARG(QVariant, result));
+ QCOMPARE(result, QVariant(expected));
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmllanguage/data/polymorphicFunctionLookup.qml b/tests/auto/qml/qqmllanguage/data/polymorphicFunctionLookup.qml
new file mode 100644
index 0000000000..4a3cc52793
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/polymorphicFunctionLookup.qml
@@ -0,0 +1,14 @@
+import QtQml 2.0
+QtObject {
+ id: root
+ property bool testFunc;
+ property bool ok: false
+ property QtObject subObject: QtObject {
+ function testFunc()
+ {
+ root.ok = true
+ }
+
+ Component.onCompleted: testFunc()
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index d890668655..bb6e9582c2 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1392,7 +1392,7 @@ class ScopedEnumsWithNameClash
public:
enum class ScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3, OtherScopedEnum };
- enum class OtherScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3 };
+ enum class OtherScopedEnum : int { ScopedVal1 = 10, ScopedVal2 = 11, ScopedVal3 = 12 };
};
class ScopedEnumsWithResolvedNameClash
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 157fd500ad..7a8de739f4 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -298,6 +298,8 @@ private slots:
void retrieveQmlTypeId();
+ void polymorphicFunctionLookup();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -5049,6 +5051,17 @@ void tst_qqmllanguage::retrieveQmlTypeId()
QVERIFY(qmlTypeId("Test", 1, 0, "MyTypeObjectSingleton") >= 0);
}
+void tst_qqmllanguage::polymorphicFunctionLookup()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("polymorphicFunctionLookup.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+
+ QVERIFY(o->property("ok").toBool());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index ae02352293..ff796a5bd8 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -2676,7 +2676,7 @@ void tst_QQuickListView::sectionsSnap_data()
QTest::addColumn<int>("duration");
QTest::newRow("drag") << QQuickListView::NoSnap << QPoint(100, 45) << 500;
- QTest::newRow("flick") << QQuickListView::SnapOneItem << QPoint(100, 75) << 50;
+ QTest::newRow("flick") << QQuickListView::SnapOneItem << QPoint(100, 60) << 100;
}
void tst_QQuickListView::sectionsSnap()