aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmllint
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qmllint')
-rw-r--r--tests/auto/qml/qmllint/CMakeLists.txt12
-rw-r--r--tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/A.qml5
-rw-r--r--tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/qmldir2
-rw-r--r--tests/auto/qml/qmllint/data/IsNotAnEntryOfEnum.qml14
-rw-r--r--tests/auto/qml/qmllint/data/LocaleTest/localeTest.qmltypes31
-rw-r--r--tests/auto/qml/qmllint/data/LocaleTest/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/Outer.qml5
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/multi.qrc10
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/qml/Inner.qml5
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/Page.qml5
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/qmldir1
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/qml/qmldir1
-rw-r--r--tests/auto/qml/qmllint/data/MultiDirectory/qmldir5
-rw-r--r--tests/auto/qml/qmllint/data/MyStyle/MyStyle.qmltypes112
-rw-r--r--tests/auto/qml/qmllint/data/MyStyle/ToolBar.qml12
-rw-r--r--tests/auto/qml/qmllint/data/MyStyle/qmldir4
-rw-r--r--tests/auto/qml/qmllint/data/NeedImportPath.qml5
-rw-r--r--tests/auto/qml/qmllint/data/Qtbug111015/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/Qtbug111015/qtbug111015.qmltypes20
-rw-r--r--tests/auto/qml/qmllint/data/SharedFunctions.js5
-rw-r--r--tests/auto/qml/qmllint/data/StringToDateTime/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/StringToDateTime/stringToDateTime.qmltypes14
-rw-r--r--tests/auto/qml/qmllint/data/TestTypes/testtypes.qmltypes20
-rw-r--r--tests/auto/qml/qmllint/data/Things/plugins.qmltypes20
-rw-r--r--tests/auto/qml/qmllint/data/UnqualifiedInStoreSloppy.qml12
-rw-r--r--tests/auto/qml/qmllint/data/UnqualifiedInStoreStrict.qml12
-rw-r--r--tests/auto/qml/qmllint/data/addressableValue.qml8
-rw-r--r--tests/auto/qml/qmllint/data/attachedImportUse.qml7
-rw-r--r--tests/auto/qml/qmllint/data/badAliasNotAnExpression.qml8
-rw-r--r--tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes513
-rw-r--r--tests/auto/qml/qmllint/data/coercetovoid.qml8
-rw-r--r--tests/auto/qml/qmllint/data/customParser.qml4
-rw-r--r--tests/auto/qml/qmllint/data/dontCheckJSTypes.qml11
-rw-r--r--tests/auto/qml/qmllint/data/findMemberPrint.qml13
-rw-r--r--tests/auto/qml/qmllint/data/generalizedGroupHint.qml23
-rw-r--r--tests/auto/qml/qmllint/data/groupedAttachedLayout.qml20
-rw-r--r--tests/auto/qml/qmllint/data/hidden/moduleWithQrc/main.qml11
-rw-r--r--tests/auto/qml/qmllint/data/hidden/moduleWithQrc/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/hidden/moduleWithQrc_raw_qml_0.qrc6
-rw-r--r--tests/auto/qml/qmllint/data/hidden/qmake_moduleWithQrc.qrc6
-rw-r--r--tests/auto/qml/qmllint/data/importNonexistentFile.qml3
-rw-r--r--tests/auto/qml/qmllint/data/importNullDevice.qml3
-rw-r--r--tests/auto/qml/qmllint/data/initReadonly.qml1
-rw-r--r--tests/auto/qml/qmllint/data/inlineComponent.qml1
-rw-r--r--tests/auto/qml/qmllint/data/invalidIdLookup.qml10
-rw-r--r--tests/auto/qml/qmllint/data/jsonArrayIsRecognized.qml8
-rw-r--r--tests/auto/qml/qmllint/data/jsonObjectIsRecognized.qml8
-rw-r--r--tests/auto/qml/qmllint/data/locale.qml6
-rw-r--r--tests/auto/qml/qmllint/data/lowerCaseQualifiedImport.qml9
-rw-r--r--tests/auto/qml/qmllint/data/lowerCaseQualifiedImport2.qml9
-rw-r--r--tests/auto/qml/qmllint/data/multifix.fixed.qml14
-rw-r--r--tests/auto/qml/qmllint/data/multifix.qml13
-rw-r--r--tests/auto/qml/qmllint/data/notQmlRootMethods.qml8
-rw-r--r--tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml1
-rw-r--r--tests/auto/qml/qmllint/data/pluginQuick_propertyChangesInvalidTarget.qml8
-rw-r--r--tests/auto/qml/qmllint/data/pluginQuick_propertyChangesParsed.qml19
-rw-r--r--tests/auto/qml/qmllint/data/qEventPoint.qml9
-rw-r--r--tests/auto/qml/qmllint/data/qmlRootMethods.qml12
-rw-r--r--tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml2
-rw-r--r--tests/auto/qml/qmllint/data/returnTypeAnnotation_component.qml9
-rw-r--r--tests/auto/qml/qmllint/data/returnTypeAnnotation_enum.qml5
-rw-r--r--tests/auto/qml/qmllint/data/returnTypeAnnotation_method.qml6
-rw-r--r--tests/auto/qml/qmllint/data/returnTypeAnnotation_property.qml7
-rw-r--r--tests/auto/qml/qmllint/data/returnTypeAnnotation_type.qml5
-rw-r--r--tests/auto/qml/qmllint/data/scriptInTemplate.qml6
-rw-r--r--tests/auto/qml/qmllint/data/scripts/Foo.js6
-rw-r--r--tests/auto/qml/qmllint/data/scripts/qmldir4
-rw-r--r--tests/auto/qml/qmllint/data/scripts/scripts.qmltypes22
-rw-r--r--tests/auto/qml/qmllint/data/scriptstring.qml73
-rw-r--r--tests/auto/qml/qmllint/data/settings/plugin/.qmllint.ini2
-rw-r--r--tests/auto/qml/qmllint/data/settings/plugin/elemenpass_pluginSettingTest.qml7
-rw-r--r--tests/auto/qml/qmllint/data/something.qml2
-rw-r--r--tests/auto/qml/qmllint/data/storeNameMethod.qml12
-rw-r--r--tests/auto/qml/qmllint/data/stringToDateTime.qml7
-rw-r--r--tests/auto/qml/qmllint/data/untitled/components/Foo.qml5
-rw-r--r--tests/auto/qml/qmllint/data/untitled/main.qml9
-rw-r--r--tests/auto/qml/qmllint/data/untitled/qrcUrlImport.qrc6
-rw-r--r--tests/auto/qml/qmllint/data/useConstInvokable.qml5
-rw-r--r--tests/auto/qml/qmllint/data/validLiterals.qml6
-rw-r--r--tests/auto/qml/qmllint/data/valueTypesFromString.qml7
-rw-r--r--tests/auto/qml/qmllint/data/variantMapLookup.qml13
-rw-r--r--tests/auto/qml/qmllint/data/writeListProperty.qml7
-rw-r--r--tests/auto/qml/qmllint/lintplugin.cpp48
-rw-r--r--tests/auto/qml/qmllint/lintplugin.h4
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp531
85 files changed, 1839 insertions, 101 deletions
diff --git a/tests/auto/qml/qmllint/CMakeLists.txt b/tests/auto/qml/qmllint/CMakeLists.txt
index 422e7a08b3..5a3e2d9c0d 100644
--- a/tests/auto/qml/qmllint/CMakeLists.txt
+++ b/tests/auto/qml/qmllint/CMakeLists.txt
@@ -7,6 +7,12 @@
## tst_qmllint Test:
#####################################################################
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(tst_qmllint LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
# Collect test data
file(GLOB_RECURSE test_data_glob
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -42,9 +48,15 @@ qt_internal_extend_target(tst_qmllint CONDITION NOT ANDROID AND NOT IOS
QT_QMLTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data"
)
+if (TARGET qmllint)
+ add_dependencies(tst_qmllint Qt::qmllint)
+endif()
+
if (TARGET qmljsrootgen)
qt_internal_extend_target(tst_qmllint
DEFINES
QT_QMLJSROOTGEN_PRESENT
)
+
+ add_dependencies(tst_qmllint Qt::qmljsrootgen)
endif()
diff --git a/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/A.qml b/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/A.qml
new file mode 100644
index 0000000000..4141884af9
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/A.qml
@@ -0,0 +1,5 @@
+import QtQuick
+
+Item {
+ property string myProperty
+}
diff --git a/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/qmldir b/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/qmldir
new file mode 100644
index 0000000000..b6e958d657
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/ImportPath/ModuleInImportPath/qmldir
@@ -0,0 +1,2 @@
+module ModuleInImportPath
+A 1.0 A.qml
diff --git a/tests/auto/qml/qmllint/data/IsNotAnEntryOfEnum.qml b/tests/auto/qml/qmllint/data/IsNotAnEntryOfEnum.qml
new file mode 100644
index 0000000000..8b20fe9ae9
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/IsNotAnEntryOfEnum.qml
@@ -0,0 +1,14 @@
+import QtQuick
+
+Item {
+ id: item
+ visible: true
+
+ enum Mode {
+ Hours,
+ Minutes
+ }
+
+ property int mode: item.Mode.Hours
+ property string s: item.mode === IsNotAnEntryOfEnum.Mode.Hour ? "green" : "tomato"
+}
diff --git a/tests/auto/qml/qmllint/data/LocaleTest/localeTest.qmltypes b/tests/auto/qml/qmllint/data/LocaleTest/localeTest.qmltypes
new file mode 100644
index 0000000000..b5baa22357
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/LocaleTest/localeTest.qmltypes
@@ -0,0 +1,31 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by qmltyperegistrar.
+
+Module {
+ Component {
+ file: "AppManager.h"
+ name: "AppManager"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["LocaleTest/AppManager 1.0"]
+ isCreatable: false
+ isSingleton: true
+ exportMetaObjectRevisions: [256]
+ Property {
+ name: "primaryLocale"
+ type: "QLocale"
+ read: "getPrimaryLocale"
+ notify: "primaryLocaleChanged"
+ index: 0
+ isReadonly: true
+ }
+ Signal {
+ name: "primaryLocaleChanged"
+ Parameter { type: "QLocale" }
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/LocaleTest/qmldir b/tests/auto/qml/qmllint/data/LocaleTest/qmldir
new file mode 100644
index 0000000000..2dc0799d5b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/LocaleTest/qmldir
@@ -0,0 +1,3 @@
+module LocaleTest
+typeinfo localeTest.qmltypes
+depends QtQml
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/Outer.qml b/tests/auto/qml/qmllint/data/MultiDirectory/Outer.qml
new file mode 100644
index 0000000000..5dda9a4d12
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/Outer.qml
@@ -0,0 +1,5 @@
+import QtQml
+
+QtObject {
+ property int o: 12
+}
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/multi.qrc b/tests/auto/qml/qmllint/data/MultiDirectory/multi.qrc
new file mode 100644
index 0000000000..b6df21ec4c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/multi.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/qt/qml/MultiDirectory">
+ <file>qmldir</file>
+ <file>Outer.qml</file>
+ <file>qml/qmldir</file>
+ <file>qml/Inner.qml</file>
+ <file>qml/pages/qmldir</file>
+ <file>qml/pages/Page.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/qml/Inner.qml b/tests/auto/qml/qmllint/data/MultiDirectory/qml/Inner.qml
new file mode 100644
index 0000000000..01b7c331d9
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/qml/Inner.qml
@@ -0,0 +1,5 @@
+import QtQml
+
+Outer {
+ o: 25
+}
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/Page.qml b/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/Page.qml
new file mode 100644
index 0000000000..7efc889fb1
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/Page.qml
@@ -0,0 +1,5 @@
+import QtQml
+
+Inner {
+ o: 32
+}
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/qmldir b/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/qmldir
new file mode 100644
index 0000000000..56ef19d41b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/qml/pages/qmldir
@@ -0,0 +1 @@
+prefer :/qt/qml/MultiDirectory/
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/qml/qmldir b/tests/auto/qml/qmllint/data/MultiDirectory/qml/qmldir
new file mode 100644
index 0000000000..56ef19d41b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/qml/qmldir
@@ -0,0 +1 @@
+prefer :/qt/qml/MultiDirectory/
diff --git a/tests/auto/qml/qmllint/data/MultiDirectory/qmldir b/tests/auto/qml/qmllint/data/MultiDirectory/qmldir
new file mode 100644
index 0000000000..699132dc4f
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MultiDirectory/qmldir
@@ -0,0 +1,5 @@
+module MultiDirectory
+prefer :/qt/qml/MultiDirectory
+Outer 1.0 Outer.qml
+Inner 1.0 qml/Inner.qml
+Page 1.0 qml/pages/Page.qml
diff --git a/tests/auto/qml/qmllint/data/MyStyle/MyStyle.qmltypes b/tests/auto/qml/qmllint/data/MyStyle/MyStyle.qmltypes
new file mode 100644
index 0000000000..92c1b0953e
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MyStyle/MyStyle.qmltypes
@@ -0,0 +1,112 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by qmltyperegistrar.
+
+Module {
+ Component {
+ file: "mystyle.h"
+ name: "MyStyle"
+ accessSemantics: "reference"
+ prototype: "QQuickAttachedPropertyPropagator"
+ exports: ["MyStyle/MyStyle 1.0", "MyStyle/MyStyle 254.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [256, 65024]
+ attachedType: "MyStyle"
+ Enum {
+ name: "Theme"
+ values: ["Light", "Dark"]
+ }
+ Property {
+ name: "theme"
+ type: "Theme"
+ read: "theme"
+ write: "setTheme"
+ reset: "resetTheme"
+ notify: "themeChanged"
+ index: 0
+ isFinal: true
+ }
+ Property {
+ name: "windowColor"
+ type: "QColor"
+ read: "windowColor"
+ notify: "themeChanged"
+ index: 1
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "windowTextColor"
+ type: "QColor"
+ read: "windowTextColor"
+ notify: "themeChanged"
+ index: 2
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "buttonColor"
+ type: "QColor"
+ read: "buttonColor"
+ notify: "themeChanged"
+ index: 3
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "buttonTextColor"
+ type: "QColor"
+ read: "buttonTextColor"
+ notify: "themeChanged"
+ index: 4
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "toolBarColor"
+ type: "QColor"
+ read: "toolBarColor"
+ notify: "themeChanged"
+ index: 5
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "popupColor"
+ type: "QColor"
+ read: "popupColor"
+ notify: "themeChanged"
+ index: 6
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "popupBorderColor"
+ type: "QColor"
+ read: "popupBorderColor"
+ notify: "themeChanged"
+ index: 7
+ isReadonly: true
+ isFinal: true
+ }
+ Property {
+ name: "backgroundDimColor"
+ type: "QColor"
+ read: "backgroundDimColor"
+ notify: "themeChanged"
+ index: 8
+ isReadonly: true
+ isFinal: true
+ }
+ Signal { name: "themeChanged" }
+ }
+ Component {
+ file: "qquickattachedpropertypropagator.h"
+ name: "QQuickAttachedPropertyPropagator"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/MyStyle/ToolBar.qml b/tests/auto/qml/qmllint/data/MyStyle/ToolBar.qml
new file mode 100644
index 0000000000..5920797d9b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MyStyle/ToolBar.qml
@@ -0,0 +1,12 @@
+import QtQuick
+import QtQuick.Templates as T
+import MyStyle
+
+T.ToolBar {
+ id: control
+
+ property color c: MyStyle.toolBarColor
+ background: Rectangle {
+ color: MyStyle.toolBarColor
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/MyStyle/qmldir b/tests/auto/qml/qmllint/data/MyStyle/qmldir
new file mode 100644
index 0000000000..8cc4246f7c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MyStyle/qmldir
@@ -0,0 +1,4 @@
+module MyStyle
+typeinfo MyStyle.qmltypes
+ToolBar 254.0 ToolBar.qml
+import QtQuick.Controls.Material
diff --git a/tests/auto/qml/qmllint/data/NeedImportPath.qml b/tests/auto/qml/qmllint/data/NeedImportPath.qml
new file mode 100644
index 0000000000..0a63b58f7c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/NeedImportPath.qml
@@ -0,0 +1,5 @@
+import ModuleInImportPath
+
+A {
+ myProperty: "Hello World"
+}
diff --git a/tests/auto/qml/qmllint/data/Qtbug111015/qmldir b/tests/auto/qml/qmllint/data/Qtbug111015/qmldir
new file mode 100644
index 0000000000..3bf1d48e13
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Qtbug111015/qmldir
@@ -0,0 +1,3 @@
+module Qtbug111015
+typeinfo qtbug111015.qmltypes
+import QtQml
diff --git a/tests/auto/qml/qmllint/data/Qtbug111015/qtbug111015.qmltypes b/tests/auto/qml/qmllint/data/Qtbug111015/qtbug111015.qmltypes
new file mode 100644
index 0000000000..7de521a379
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Qtbug111015/qtbug111015.qmltypes
@@ -0,0 +1,20 @@
+import QtQuick.tooling 1.2
+
+Module {
+ Component {
+ file: "typewithjsonobjectlist.h"
+ name: "TypeWithJsonObjectList"
+ exports: ["QmlLintTestLib/TypeWithJsonObjectList 1.0"]
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Property { name: "jsonObjectList"; type: "QJsonObject"; isList: true; read: "getJsonObjectList"; index: 0; isReadonly: true }
+ }
+ Component {
+ file: "typewithjsonarray.h"
+ name: "TypeWithJsonArray"
+ exports: ["QmlLintTestLib/TypeWithJsonArray 1.0"]
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Property { name: "jsonArray"; type: "QJsonArray"; read: "getJsonArray"; index: 0; isReadonly: true }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/SharedFunctions.js b/tests/auto/qml/qmllint/data/SharedFunctions.js
new file mode 100644
index 0000000000..3398d2d6d7
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/SharedFunctions.js
@@ -0,0 +1,5 @@
+.pragma library
+
+function setColorAlpha(color, alpha) {
+ return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha)
+}
diff --git a/tests/auto/qml/qmllint/data/StringToDateTime/qmldir b/tests/auto/qml/qmllint/data/StringToDateTime/qmldir
new file mode 100644
index 0000000000..761f613496
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/StringToDateTime/qmldir
@@ -0,0 +1,3 @@
+module StringToDateTime
+typeinfo stringToDateTime.qmltypes
+import QtQml
diff --git a/tests/auto/qml/qmllint/data/StringToDateTime/stringToDateTime.qmltypes b/tests/auto/qml/qmllint/data/StringToDateTime/stringToDateTime.qmltypes
new file mode 100644
index 0000000000..e0f13fa2ec
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/StringToDateTime/stringToDateTime.qmltypes
@@ -0,0 +1,14 @@
+import QtQuick.tooling 1.2
+Module {
+ Component {
+ file: "stringToQDateTime.h"
+ name: "StringToDateTimeComponent"
+ exports: ["QmlLintTestLib/StringToDateTime 1.0"]
+ exportMetaObjectRevisions: [256]
+ accessSemantics: "reference"
+ prototype: "QObject"
+ Property { name: "aDate"; type: "QDate"; read: "getADate"; write: "setADate" }
+ Property { name: "aTime"; type: "QTime"; read: "getATime"; write: "setATime" }
+ Property { name: "aDateTime"; type: "QDateTime"; read: "getADateTime"; write: "setADateTime" }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/TestTypes/testtypes.qmltypes b/tests/auto/qml/qmllint/data/TestTypes/testtypes.qmltypes
index 04ca30c184..77ad6a3cef 100644
--- a/tests/auto/qml/qmllint/data/TestTypes/testtypes.qmltypes
+++ b/tests/auto/qml/qmllint/data/TestTypes/testtypes.qmltypes
@@ -178,4 +178,24 @@ Module {
exportMetaObjectRevisions: [256]
Method { name: "createObject"; isJavaScriptFunction: true }
}
+ Component {
+ file: "variantMapLookup.h"
+ name: "VariantMapLookupFoo"
+ prototype: "QObject"
+ exports: ["TestTypes/VariantMapLookupFoo 1.0"]
+ exportMetaObjectRevisions: [256]
+ Property {
+ name: "data"
+ type: "QVariantMap"
+ read: "data"
+ index: 0
+ }
+ }
+ Component {
+ file: "foo.h"
+ name: "Foo"
+ prototype: "QObject"
+ exports: ["TestTypes/Foo 1.0"]
+ Method { name: "print" }
+ }
}
diff --git a/tests/auto/qml/qmllint/data/Things/plugins.qmltypes b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
index 9d36d91a90..3b0da602ac 100644
--- a/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
+++ b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
@@ -12,6 +12,7 @@ Module {
exports: ["Things/SomethingEntirelyStrange 1.0"]
Enum {
name: "AnEnum"
+ isScoped: true
values: {
"AAA": 0,
"BBB": 1,
@@ -20,7 +21,7 @@ Module {
}
Enum {
name: "TheEnum"
- scoped: false
+ isScoped: false
values: {
"V1": 0,
"V2": 1
@@ -96,4 +97,21 @@ Module {
Property { name: "foo"; type: "string" }
hasCustomParser: true
}
+ Component {
+ file: "mediaplayer-qml.h"
+ name: "MediaPlayerStateMachine"
+ accessSemantics: "value"
+ exports: ["Mediaplayer/MediaPlayerStateMachine 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [256]
+ }
+ Component {
+ file: "constinvokable.h"
+ name: "ConstInvokable"
+ accessSemantics: "reference"
+ prototype: "QObject"
+ exports: ["Things/ConstInvokable 1.0"]
+ exportMetaObjectRevisions: [256]
+ Method { name: "getObject"; type: "QObject"; isPointer: true; isTypeConstant: true }
+ }
}
diff --git a/tests/auto/qml/qmllint/data/UnqualifiedInStoreSloppy.qml b/tests/auto/qml/qmllint/data/UnqualifiedInStoreSloppy.qml
new file mode 100644
index 0000000000..197b74fa60
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/UnqualifiedInStoreSloppy.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+
+Window {
+ Rectangle {
+ property real divisor: 0
+
+ Timer {
+ onTriggered: divisor = 1
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/UnqualifiedInStoreStrict.qml b/tests/auto/qml/qmllint/data/UnqualifiedInStoreStrict.qml
new file mode 100644
index 0000000000..198e2146f5
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/UnqualifiedInStoreStrict.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+
+Window {
+ Rectangle {
+ property real divisor: 0
+
+ Timer {
+ onTriggered: function() {"use strict"; divisor = 1 }
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/addressableValue.qml b/tests/auto/qml/qmllint/data/addressableValue.qml
new file mode 100644
index 0000000000..9b93728ed8
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/addressableValue.qml
@@ -0,0 +1,8 @@
+pragma ValueTypeBehavior: Addressable
+
+import QtQml
+import scripts
+
+QtObject {
+ property var v: "red" as vvv
+}
diff --git a/tests/auto/qml/qmllint/data/attachedImportUse.qml b/tests/auto/qml/qmllint/data/attachedImportUse.qml
new file mode 100644
index 0000000000..56b4e2bf7c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/attachedImportUse.qml
@@ -0,0 +1,7 @@
+import QtQml
+import TestTypes
+
+QtObject {
+ id: control
+ objectName: control.BirthdayParty.objectName
+}
diff --git a/tests/auto/qml/qmllint/data/badAliasNotAnExpression.qml b/tests/auto/qml/qmllint/data/badAliasNotAnExpression.qml
new file mode 100644
index 0000000000..cdc2b28c07
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/badAliasNotAnExpression.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+Item {
+
+ property alias innerObj: {
+ id: inner
+ }
+
+}
diff --git a/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes b/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes
new file mode 100644
index 0000000000..96f98dd14e
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/bad_builtins/builtins.qmltypes
@@ -0,0 +1,513 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -builtins'
+
+Module {
+ dependencies: []
+ Component {
+ name: "Qt"
+ Enum {
+ name: "GlobalColor"
+ values: {
+ "color0": 0,
+ "color1": 1,
+ "black": 2,
+ "white": 3,
+ "darkGray": 4,
+ "gray": 5,
+ "lightGray": 6,
+ "red": 7,
+ "green": 8,
+ "blue": 9,
+ "cyan": 10,
+ "magenta": 11,
+ "yellow": 12,
+ "darkRed": 13,
+ "darkGreen": 14,
+ "darkBlue": 15,
+ "darkCyan": 16,
+ "darkMagenta": 17,
+ "darkYellow": 18,
+ "transparent": 19
+ }
+ }
+ Enum {
+ name: "KeyboardModifiers"
+ values: {
+ "NoModifier": 0,
+ "ShiftModifier": 33554432,
+ "ControlModifier": 67108864,
+ "AltModifier": 134217728,
+ "MetaModifier": 268435456,
+ "KeypadModifier": 536870912,
+ "GroupSwitchModifier": 1073741824,
+ "KeyboardModifierMask": -33554432
+ }
+ }
+ Enum {
+ name: "MouseButtons"
+ values: {
+ "NoButton": 0,
+ "LeftButton": 1,
+ "RightButton": 2,
+ "MidButton": 4, // For backwards compatibility
+ "MiddleButton": 4,
+ "BackButton": 8,
+ "XButton1": 8,
+ "ExtraButton1": 8,
+ "ForwardButton": 16,
+ "XButton2": 16,
+ "ExtraButton2": 16,
+ "TaskButton": 32,
+ "ExtraButton3": 32,
+ "ExtraButton4": 64,
+ "ExtraButton5": 128,
+ "ExtraButton6": 256,
+ "ExtraButton7": 512,
+ "ExtraButton8": 1024,
+ "ExtraButton9": 2048,
+ "ExtraButton10": 4096,
+ "ExtraButton11": 8192,
+ "ExtraButton12": 16384,
+ "ExtraButton13": 32768,
+ "ExtraButton14": 65536,
+ "ExtraButton15": 131072,
+ "ExtraButton16": 262144,
+ "ExtraButton17": 524288,
+ "ExtraButton18": 1048576,
+ "ExtraButton19": 2097152,
+ "ExtraButton20": 4194304,
+ "ExtraButton21": 8388608,
+ "ExtraButton22": 16777216,
+ "ExtraButton23": 33554432,
+ "ExtraButton24": 67108864,
+ "AllButtons": 134217727,
+ "MaxMouseButton": 67108864,
+ "MouseButtonMask": -1
+ }
+ }
+ Enum {
+ name: "Orientation"
+ values: {
+ "Horizontal": 1,
+ "Vertical": 2
+ }
+ }
+ Enum {
+ name: "Orientations"
+ values: {
+ "Horizontal": 1,
+ "Vertical": 2
+ }
+ }
+ Enum {
+ name: "FocusPolicy"
+ values: {
+ "NoFocus": 0,
+ "TabFocus": 1,
+ "ClickFocus": 2,
+ "StrongFocus": 11,
+ "WheelFocus": 15
+ }
+ }
+ Enum {
+ name: "TabFocusBehavior"
+ values: {
+ "NoTabFocus": 0,
+ "TabFocusTextControls": 1,
+ "TabFocusListControls": 2,
+ "TabFocusAllControls": 255
+ }
+ }
+ Enum {
+ name: "SortOrder"
+ values: {
+ "AscendingOrder": 0,
+ "DescendingOrder": 1
+ }
+ }
+ Enum {
+ name: "SplitBehavior"
+ values: {
+ "KeepEmptyParts": 0,
+ "SkipEmptyParts": 1
+ }
+ }
+ Enum {
+ name: "Alignment"
+ values: {
+ "AlignLeft": 1,
+ "AlignLeading": 1,
+ "AlignRight": 2,
+ "AlignTrailing": 2,
+ "AlignHCenter": 4,
+ "AlignJustify": 8,
+ "AlignAbsolute": 16,
+ "AlignHorizontal_Mask": 31,
+ "AlignTop": 32,
+ "AlignBottom": 64,
+ "AlignVCenter": 128,
+ "AlignBaseline": 256,
+ "AlignVertical_Mask": 480,
+ "AlignCenter": 132
+ }
+ }
+ Enum {
+ name: "TextFlag"
+ values: {
+ "TextSingleLine": 256,
+ "TextDontClip": 512,
+ "TextExpandTabs": 1024,
+ "TextShowMnemonic": 2048,
+ "TextWordWrap": 4096,
+ "TextWrapAnywhere": 8192,
+ "TextDontPrint": 16384,
+ "TextIncludeTrailingSpaces": 134217728,
+ "TextHideMnemonic": 32768,
+ "TextJustificationForced": 65536,
+ "TextForceLeftToRight": 131072,
+ "TextForceRightToLeft": 262144,
+ "TextLongestVariant": 524288,
+ "TextBypassShaping": 1048576
+ }
+ }
+ Enum {
+ name: "TextElideMode"
+ values: {
+ "ElideLeft": 0,
+ "ElideRight": 1,
+ "ElideMiddle": 2,
+ "ElideNone": 3
+ }
+ }
+ Enum {
+ name: "WindowType"
+ values: {
+ "Widget": 0,
+ "Window": 1,
+ "Dialog": 3,
+ "Sheet": 5,
+ "Drawer": 7,
+ "Popup": 9,
+ "Tool": 11,
+ "ToolTip": 13,
+ "SplashScreen": 15,
+ "Desktop": 17,
+ "SubWindow": 18,
+ "ForeignWindow": 33,
+ "CoverWindow": 65,
+ "WindowType_Mask": 255,
+ "MSWindowsFixedSizeDialogHint": 256,
+ "MSWindowsOwnDC": 512,
+ "BypassWindowManagerHint": 1024,
+ "X11BypassWindowManagerHint": 1024,
+ "FramelessWindowHint": 2048,
+ "WindowTitleHint": 4096,
+ "WindowSystemMenuHint": 8192,
+ "WindowMinimizeButtonHint": 16384,
+ "WindowMaximizeButtonHint": 32768,
+ "WindowMinMaxButtonsHint": 49152,
+ "WindowContextHelpButtonHint": 65536,
+ "WindowShadeButtonHint": 131072,
+ "WindowStaysOnTopHint": 262144,
+ "WindowTransparentForInput": 524288,
+ "WindowOverridesSystemGestures": 1048576,
+ "WindowDoesNotAcceptFocus": 2097152,
+ "MaximizeUsingFullscreenGeometryHint": 4194304,
+ "CustomizeWindowHint": 33554432,
+ "WindowStaysOnBottomHint": 67108864,
+ "WindowCloseButtonHint": 134217728,
+ "MacWindowToolBarButtonHint": 268435456,
+ "BypassGraphicsProxyWidget": 536870912,
+ "NoDropShadowWindowHint": 1073741824,
+ "WindowFullscreenButtonHint": -2147483648
+ }
+ }
+ Enum {
+ name: "WindowFlags"
+ values: {
+ "Widget": 0,
+ "Window": 1,
+ "Dialog": 3,
+ "Sheet": 5,
+ "Drawer": 7,
+ "Popup": 9,
+ "Tool": 11,
+ "ToolTip": 13,
+ "SplashScreen": 15,
+ "Desktop": 17,
+ "SubWindow": 18,
+ "ForeignWindow": 33,
+ "CoverWindow": 65,
+ "WindowType_Mask": 255,
+ "MSWindowsFixedSizeDialogHint": 256,
+ "MSWindowsOwnDC": 512,
+ "BypassWindowManagerHint": 1024,
+ "X11BypassWindowManagerHint": 1024,
+ "FramelessWindowHint": 2048,
+ "WindowTitleHint": 4096,
+ "WindowSystemMenuHint": 8192,
+ "WindowMinimizeButtonHint": 16384,
+ "WindowMaximizeButtonHint": 32768,
+ "WindowMinMaxButtonsHint": 49152,
+ "WindowContextHelpButtonHint": 65536,
+ "WindowShadeButtonHint": 131072,
+ "WindowStaysOnTopHint": 262144,
+ "WindowTransparentForInput": 524288,
+ "WindowOverridesSystemGestures": 1048576,
+ "WindowDoesNotAcceptFocus": 2097152,
+ "MaximizeUsingFullscreenGeometryHint": 4194304,
+ "CustomizeWindowHint": 33554432,
+ "WindowStaysOnBottomHint": 67108864,
+ "WindowCloseButtonHint": 134217728,
+ "MacWindowToolBarButtonHint": 268435456,
+ "BypassGraphicsProxyWidget": 536870912,
+ "NoDropShadowWindowHint": 1073741824,
+ "WindowFullscreenButtonHint": -2147483648
+ }
+ }
+ Enum {
+ name: "WindowState"
+ values: {
+ "WindowNoState": 0,
+ "WindowMinimized": 1,
+ "WindowMaximized": 2,
+ "WindowFullScreen": 4,
+ "WindowActive": 8
+ }
+ }
+ Enum {
+ name: "WindowStates"
+ values: {
+ "WindowNoState": 0,
+ "WindowMinimized": 1,
+ "WindowMaximized": 2,
+ "WindowFullScreen": 4,
+ "WindowActive": 8
+ }
+ }
+ Enum {
+ name: "ApplicationState"
+ values: {
+ "ApplicationSuspended": 0,
+ "ApplicationHidden": 1,
+ "ApplicationInactive": 2,
+ "ApplicationActive": 4
+ }
+ }
+ Enum {
+ name: "ScreenOrientation"
+ values: {
+ "PrimaryOrientation": 0,
+ "PortraitOrientation": 1,
+ "LandscapeOrientation": 2,
+ "InvertedPortraitOrientation": 4,
+ "InvertedLandscapeOrientation": 8
+ }
+ }
+ Enum {
+ name: "ScreenOrientations"
+ values: {
+ "PrimaryOrientation": 0,
+ "PortraitOrientation": 1,
+ "LandscapeOrientation": 2,
+ "InvertedPortraitOrientation": 4,
+ "InvertedLandscapeOrientation": 8
+ }
+ }
+ Enum {
+ name: "WidgetAttribute"
+ values: {
+ "WA_Disabled": 0,
+ "WA_UnderMouse": 1,
+ "WA_MouseTracking": 2,
+ "WA_ContentsPropagated": 3,
+ "WA_OpaquePaintEvent": 4,
+ "WA_NoBackground": 4,
+ "WA_StaticContents": 5,
+ "WA_LaidOut": 7,
+ "WA_PaintOnScreen": 8,
+ "WA_NoSystemBackground": 9,
+ "WA_UpdatesDisabled": 10,
+ "WA_Mapped": 11,
+ "WA_MacNoClickThrough": 12,
+ "WA_InputMethodEnabled": 14,
+ "WA_WState_Visible": 15,
+ "WA_WState_Hidden": 16,
+ "WA_ForceDisabled": 32,
+ "WA_KeyCompression": 33,
+ "WA_PendingMoveEvent": 34,
+ "WA_PendingResizeEvent": 35,
+ "WA_SetPalette": 36,
+ "WA_SetFont": 37,
+ "WA_SetCursor": 38,
+ "WA_NoChildEventsFromChildren": 39,
+ "WA_WindowModified": 41,
+ "WA_Resized": 42,
+ "WA_Moved": 43,
+ "WA_PendingUpdate": 44,
+ "WA_InvalidSize": 45,
+ "WA_MacBrushedMetal": 46,
+ "WA_MacMetalStyle": 46,
+ "WA_CustomWhatsThis": 47,
+ "WA_LayoutOnEntireRect": 48,
+ "WA_OutsideWSRange": 49,
+ "WA_GrabbedShortcut": 50,
+ "WA_TransparentForMouseEvents": 51,
+ "WA_PaintUnclipped": 52,
+ "WA_SetWindowIcon": 53,
+ "WA_NoMouseReplay": 54,
+ "WA_DeleteOnClose": 55,
+ "WA_RightToLeft": 56,
+ "WA_SetLayoutDirection": 57,
+ "WA_NoChildEventsForParent": 58,
+ "WA_ForceUpdatesDisabled": 59,
+ "WA_WState_Created": 60,
+ "WA_WState_CompressKeys": 61,
+ "WA_WState_InPaintEvent": 62,
+ "WA_WState_Reparented": 63,
+ "WA_WState_ConfigPending": 64,
+ "WA_WState_Polished": 66,
+ "WA_WState_DND": 67,
+ "WA_WState_OwnSizePolicy": 68,
+ "WA_WState_ExplicitShowHide": 69,
+ "WA_ShowModal": 70,
+ "WA_MouseNoMask": 71,
+ "WA_GroupLeader": 72,
+ "WA_NoMousePropagation": 73,
+ "WA_Hover": 74,
+ "WA_InputMethodTransparent": 75,
+ "WA_QuitOnClose": 76,
+ "WA_KeyboardFocusChange": 77,
+ "WA_AcceptDrops": 78,
+ "WA_DropSiteRegistered": 79,
+ "WA_ForceAcceptDrops": 79,
+ "WA_WindowPropagation": 80,
+ "WA_NoX11EventCompression": 81,
+ "WA_TintedBackground": 82,
+ "WA_X11OpenGLOverlay": 83,
+ "WA_AlwaysShowToolTips": 84,
+ "WA_MacOpaqueSizeGrip": 85,
+ "WA_SetStyle": 86,
+ "WA_SetLocale": 87,
+ "WA_MacShowFocusRect": 88,
+ "WA_MacNormalSize": 89,
+ "WA_MacSmallSize": 90,
+ "WA_MacMiniSize": 91,
+ "WA_LayoutUsesWidgetRect": 92,
+ "WA_StyledBackground": 93,
+ "WA_MSWindowsUseDirect3D": 94,
+ "WA_CanHostQMdiSubWindowTitleBar": 95,
+ "WA_MacAlwaysShowToolWindow": 96,
+ "WA_StyleSheet": 97,
+ "WA_ShowWithoutActivating": 98,
+ "WA_X11BypassTransientForHint": 99,
+ "WA_NativeWindow": 100,
+ "WA_DontCreateNativeAncestors": 101,
+ "WA_MacVariableSize": 102,
+ "WA_DontShowOnScreen": 103,
+ "WA_X11NetWmWindowTypeDesktop": 104,
+ "WA_X11NetWmWindowTypeDock": 105,
+ "WA_X11NetWmWindowTypeToolBar": 106,
+ "WA_X11NetWmWindowTypeMenu": 107,
+ "WA_X11NetWmWindowTypeUtility": 108,
+ "WA_X11NetWmWindowTypeSplash": 109,
+ "WA_X11NetWmWindowTypeDialog": 110,
+ "WA_X11NetWmWindowTypeDropDownMenu": 111,
+ "WA_X11NetWmWindowTypePopupMenu": 112,
+ "WA_X11NetWmWindowTypeToolTip": 113,
+ "WA_X11NetWmWindowTypeNotification": 114,
+ "WA_X11NetWmWindowTypeCombo": 115,
+ "WA_X11NetWmWindowTypeDND": 116,
+ "WA_MacFrameworkScaled": 117,
+ "WA_SetWindowModality": 118,
+ "WA_WState_WindowOpacitySet": 119,
+ "WA_TranslucentBackground": 120,
+ "WA_AcceptTouchEvents": 121,
+ "WA_WState_AcceptedTouchBeginEvent": 122,
+ "WA_TouchPadAcceptSingleTouchEvents": 123,
+ "WA_X11DoNotAcceptFocus": 126,
+ "WA_MacNoShadow": 127,
+ "WA_AlwaysStackOnTop": 128,
+ "WA_TabletTracking": 129,
+ "WA_ContentsMarginsRespectsSafeArea": 130,
+ "WA_StyleSheetTarget": 131,
+ "WA_AttributeCount": 132
+ }
+ }
+ Enum {
+ name: "ApplicationAttribute"
+ values: {
+ "AA_ImmediateWidgetCreation": 0,
+ "AA_MSWindowsUseDirect3DByDefault": 1,
+ "AA_DontShowIconsInMenus": 2,
+ "AA_NativeWindows": 3,
+ "AA_DontCreateNativeWidgetSiblings": 4,
+ "AA_PluginApplication": 5,
+ "AA_MacPluginApplication": 5,
+ "AA_DontUseNativeMenuBar": 6,
+ "AA_MacDontSwapCtrlAndMeta": 7,
+ "AA_Use96Dpi": 8,
+ "AA_X11InitThreads": 10,
+ "AA_SynthesizeTouchForUnhandledMouseEvents": 11,
+ "AA_SynthesizeMouseForUnhandledTouchEvents": 12,
+ "AA_UseHighDpiPixmaps": 13,
+ "AA_ForceRasterWidgets": 14,
+ "AA_UseDesktopOpenGL": 15,
+ "AA_UseOpenGLES": 16,
+ "AA_UseSoftwareOpenGL": 17,
+ "AA_ShareOpenGLContexts": 18,
+ "AA_SetPalette": 19,
+ "AA_EnableHighDpiScaling": 20,
+ "AA_DisableHighDpiScaling": 21,
+ "AA_UseStyleSheetPropagationInWidgetStyles": 22,
+ "AA_DontUseNativeDialogs": 23,
+ "AA_SynthesizeMouseForUnhandledTabletEvents": 24,
+ "AA_CompressHighFrequencyEvents": 25,
+ "AA_DontCheckOpenGLContextThreadAffinity": 26,
+ "AA_DisableShaderDiskCache": 27,
+ "AA_DontShowShortcutsInContextMenus": 28,
+ "AA_CompressTabletEvents": 29,
+ "AA_DisableWindowContextHelpButton": 30,
+ "AA_DisableSessionManager": 31,
+ "AA_AttributeCount": 32
+ }
+ }
+ Enum {
+ name: "ImageConversionFlags"
+ values: {
+ "ColorMode_Mask": 3,
+ "AutoColor": 0,
+ "ColorOnly": 3,
+ "MonoOnly": 2,
+ "AlphaDither_Mask": 12,
+ "ThresholdAlphaDither": 0,
+ "OrderedAlphaDither": 4,
+ "DiffuseAlphaDither": 8,
+ "NoAlpha": 12,
+ "Dither_Mask": 48,
+ "DiffuseDither": 0,
+ "OrderedDither": 16,
+ "ThresholdDither": 32,
+ "DitherMode_Mask": 192,
+ "AutoDither": 0,
+ "PreferDither": 64,
+ "AvoidDither": 128,
+ "NoOpaqueDetection": 256,
+ "NoFormatConversion": 512
+ }
+ }
+ Enum {
+ name: "BGMode"
+ values: {
+ "TransparentMode": 0,
+ "OpaqueMode": 1
+ }
+ }
+ }
+ Component { name: "QEasingCurve"; prototype: "QQmlEasingValueType" }
+}
diff --git a/tests/auto/qml/qmllint/data/coercetovoid.qml b/tests/auto/qml/qmllint/data/coercetovoid.qml
new file mode 100644
index 0000000000..f1b593ea3a
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/coercetovoid.qml
@@ -0,0 +1,8 @@
+pragma Strict
+import QtQml
+
+QtObject {
+ function touchThisAndReturnSomething(x: int) {
+ return x + 1;
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/customParser.qml b/tests/auto/qml/qmllint/data/customParser.qml
index a83ae7e823..324ca20953 100644
--- a/tests/auto/qml/qmllint/data/customParser.qml
+++ b/tests/auto/qml/qmllint/data/customParser.qml
@@ -7,11 +7,11 @@ Rectangle {
states: [
State {
name: "red_color"
- PropertyChanges { target: root; color: "red" }
+ PropertyChanges { root.color: "red" }
},
State {
name: "blue_color"
- PropertyChanges { target: root; color: "blue" }
+ PropertyChanges { root.color: "blue" }
}
]
}
diff --git a/tests/auto/qml/qmllint/data/dontCheckJSTypes.qml b/tests/auto/qml/qmllint/data/dontCheckJSTypes.qml
new file mode 100644
index 0000000000..dc582936b9
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/dontCheckJSTypes.qml
@@ -0,0 +1,11 @@
+import QtQuick
+
+import "SharedFunctions.js" as Functions
+
+Item {
+ Rectangle {
+ color: Functions.setColorAlpha(Qt.color("orange"), 0.15)
+ x: Functions.setColorAlpha.asdfg
+ y: Functions.asdfg
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/findMemberPrint.qml b/tests/auto/qml/qmllint/data/findMemberPrint.qml
new file mode 100644
index 0000000000..69146eb06b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/findMemberPrint.qml
@@ -0,0 +1,13 @@
+import QtQml
+
+import TestTypes
+
+QtObject {
+ property var foooooooo: Foo {
+ id: foo
+ }
+
+ function f(): void {
+ foo.print()
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/generalizedGroupHint.qml b/tests/auto/qml/qmllint/data/generalizedGroupHint.qml
new file mode 100644
index 0000000000..5fec03f7f3
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/generalizedGroupHint.qml
@@ -0,0 +1,23 @@
+import QtQuick
+
+Window {
+ width: 640
+ height: 480
+ visible: true
+ title: 'Resolve my color type'
+
+ Item {
+ id: foo
+
+ states: [
+ State {
+ PropertyChanges {
+ target: foo
+ myColor: Qt.rgba(0.5, 0.5, 0.5, 0.16)
+ }
+ }
+ ]
+
+ property color myColor: 'black'
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/groupedAttachedLayout.qml b/tests/auto/qml/qmllint/data/groupedAttachedLayout.qml
new file mode 100644
index 0000000000..7cfe98d4f8
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/groupedAttachedLayout.qml
@@ -0,0 +1,20 @@
+import QtQuick
+import QtQuick.Layouts
+
+Window {
+ id: root
+
+ Rectangle {
+ id: redRect
+ }
+
+ Item {
+ states: [
+ State {
+ PropertyChanges {
+ redRect.Layout.fillWidth: true
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/main.qml b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/main.qml
new file mode 100644
index 0000000000..d018110b86
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/main.qml
@@ -0,0 +1,11 @@
+import QtQuick
+import QtQuick.Controls
+
+Window {
+ width: 640; height: 480
+ visible: true
+
+ Button {
+ text: "a"
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/qmldir b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/qmldir
new file mode 100644
index 0000000000..acb456ffd9
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc/qmldir
@@ -0,0 +1,3 @@
+module moduleWithQrc
+prefer :/qt/qml/moduleWithQrc/
+
diff --git a/tests/auto/qml/qmllint/data/hidden/moduleWithQrc_raw_qml_0.qrc b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc_raw_qml_0.qrc
new file mode 100644
index 0000000000..43d3ec805c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/hidden/moduleWithQrc_raw_qml_0.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/qt/qml/qmllint65/">
+ <file alias="main.qml">moduleWithQrc/main.qml</file>
+ </qresource>
+</RCC>
+
diff --git a/tests/auto/qml/qmllint/data/hidden/qmake_moduleWithQrc.qrc b/tests/auto/qml/qmllint/data/hidden/qmake_moduleWithQrc.qrc
new file mode 100644
index 0000000000..cb362e2d55
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/hidden/qmake_moduleWithQrc.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/qt/qml/qmllint65">
+ <file alias="qmldir">moduleWithQrc/qmldir</file>
+ </qresource>
+</RCC>
+
diff --git a/tests/auto/qml/qmllint/data/importNonexistentFile.qml b/tests/auto/qml/qmllint/data/importNonexistentFile.qml
new file mode 100644
index 0000000000..847023936a
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/importNonexistentFile.qml
@@ -0,0 +1,3 @@
+import "¯\(ツ)/¯:/invalid/url"
+
+QtObject {}
diff --git a/tests/auto/qml/qmllint/data/importNullDevice.qml b/tests/auto/qml/qmllint/data/importNullDevice.qml
new file mode 100644
index 0000000000..5ff3090d75
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/importNullDevice.qml
@@ -0,0 +1,3 @@
+import "/dev/null"
+
+QtObject {}
diff --git a/tests/auto/qml/qmllint/data/initReadonly.qml b/tests/auto/qml/qmllint/data/initReadonly.qml
index 5a3cafff23..a9a2a0016b 100644
--- a/tests/auto/qml/qmllint/data/initReadonly.qml
+++ b/tests/auto/qml/qmllint/data/initReadonly.qml
@@ -2,4 +2,5 @@ import QtQml
QtObject {
readonly property int i: 14
+ readonly property int j: i + 20
}
diff --git a/tests/auto/qml/qmllint/data/inlineComponent.qml b/tests/auto/qml/qmllint/data/inlineComponent.qml
index ce6998a980..364d5319de 100644
--- a/tests/auto/qml/qmllint/data/inlineComponent.qml
+++ b/tests/auto/qml/qmllint/data/inlineComponent.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Item {
+ component MyIC: IC {}
component IC : QtObject {}
QtObject {
component IC2: QtObject {}
diff --git a/tests/auto/qml/qmllint/data/invalidIdLookup.qml b/tests/auto/qml/qmllint/data/invalidIdLookup.qml
new file mode 100644
index 0000000000..b351e5cfea
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/invalidIdLookup.qml
@@ -0,0 +1,10 @@
+import Things
+import QtQml
+
+QtObject {
+ property MediaPlayerStateMachine m: MediaPlayerStateMachine {
+ id: stateMachine
+ }
+
+ objectName: stateMachine.objectName
+}
diff --git a/tests/auto/qml/qmllint/data/jsonArrayIsRecognized.qml b/tests/auto/qml/qmllint/data/jsonArrayIsRecognized.qml
new file mode 100644
index 0000000000..89c52e0e52
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/jsonArrayIsRecognized.qml
@@ -0,0 +1,8 @@
+import QtQuick
+import Qtbug111015 1.0
+
+Item {
+ TypeWithJsonArray {
+ jsonArray: []
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/jsonObjectIsRecognized.qml b/tests/auto/qml/qmllint/data/jsonObjectIsRecognized.qml
new file mode 100644
index 0000000000..0a96fa9f92
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/jsonObjectIsRecognized.qml
@@ -0,0 +1,8 @@
+import QtQuick
+import Qtbug111015 1.0
+
+Item {
+ TypeWithJsonObjectList {
+ jsonObjectList: []
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/locale.qml b/tests/auto/qml/qmllint/data/locale.qml
new file mode 100644
index 0000000000..4ff9e6392c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/locale.qml
@@ -0,0 +1,6 @@
+import QtQml
+import LocaleTest
+
+QtObject {
+ property int monday: AppManager.primaryLocale.firstDayOfWeek
+}
diff --git a/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport.qml b/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport.qml
new file mode 100644
index 0000000000..14c716c35d
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport.qml
@@ -0,0 +1,9 @@
+import QtQuick as test
+
+test.Rectangle { // crashed qqmljsimportvisitor
+ id: mainRect
+ width: 100
+ height: 100
+ visible: true
+ rotation: 11
+}
diff --git a/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport2.qml b/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport2.qml
new file mode 100644
index 0000000000..4e03d8091d
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/lowerCaseQualifiedImport2.qml
@@ -0,0 +1,9 @@
+import QtQuick as test
+
+test.Item {
+ property test.color c
+
+ property var p: test.Grid {}
+
+ component IC: test.Rectangle {}
+}
diff --git a/tests/auto/qml/qmllint/data/multifix.fixed.qml b/tests/auto/qml/qmllint/data/multifix.fixed.qml
new file mode 100644
index 0000000000..d2188f2318
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/multifix.fixed.qml
@@ -0,0 +1,14 @@
+pragma ComponentBehavior: Bound
+import QtQml
+
+QtObject {
+ id: root
+
+ property Component cursorDelegate: QtObject {
+ objectName: root.objectName
+ }
+
+ property Component background: QtObject {
+ objectName: root.objectName
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/multifix.qml b/tests/auto/qml/qmllint/data/multifix.qml
new file mode 100644
index 0000000000..5f05ae7e62
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/multifix.qml
@@ -0,0 +1,13 @@
+import QtQml
+
+QtObject {
+ id: root
+
+ property Component cursorDelegate: QtObject {
+ objectName: root.objectName
+ }
+
+ property Component background: QtObject {
+ objectName: root.objectName
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/notQmlRootMethods.qml b/tests/auto/qml/qmllint/data/notQmlRootMethods.qml
new file mode 100644
index 0000000000..6d067d572d
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/notQmlRootMethods.qml
@@ -0,0 +1,8 @@
+import QtQml
+
+QtObject {
+ id: self
+
+ function a() { self.deleteLater(); }
+ function b() { self.destroyed(); }
+}
diff --git a/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml b/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
index 2a51cceac3..b6c0f59c7f 100644
--- a/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
+++ b/tests/auto/qml/qmllint/data/pluginQuick_anchorsUndefined.qml
@@ -5,5 +5,6 @@ Item {
anchors.horizontalCenter: undefined
anchors.verticalCenter: undefined
anchors.baseline: undefined
+ Component.onCompleted: anchors.bottom = undefined
}
}
diff --git a/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesInvalidTarget.qml b/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesInvalidTarget.qml
new file mode 100644
index 0000000000..fa7d4ef1ac
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesInvalidTarget.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Rectangle {
+ State {
+ name: "test"
+ PropertyChanges { target: root; color: "blue" }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesParsed.qml b/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesParsed.qml
new file mode 100644
index 0000000000..94873463f1
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/pluginQuick_propertyChangesParsed.qml
@@ -0,0 +1,19 @@
+import QtQuick
+
+Window {
+ Item {
+ id: foo
+ property color myColor: 'black'
+
+ states: [
+ State {
+ PropertyChanges {
+ target: foo
+ myColor: Qt.rgba(0.5, 0.5, 0.5, 0.16)
+ notThere: "a"
+ }
+ }
+ ]
+
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/qEventPoint.qml b/tests/auto/qml/qmllint/data/qEventPoint.qml
new file mode 100644
index 0000000000..086e710b48
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/qEventPoint.qml
@@ -0,0 +1,9 @@
+import QtQuick
+
+TapHandler {
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onSingleTapped: (eventPoint, button) => {
+ console.log("Single tap at", eventPoint, "with button", button)
+ }
+ onTapped: console.log("tapped")
+}
diff --git a/tests/auto/qml/qmllint/data/qmlRootMethods.qml b/tests/auto/qml/qmllint/data/qmlRootMethods.qml
new file mode 100644
index 0000000000..5541de3a32
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/qmlRootMethods.qml
@@ -0,0 +1,12 @@
+import QtQml
+
+QtObject {
+ id: self
+
+ objectName: self.toString()
+
+ Component.onCompleted: {
+ self.destroy();
+ self.destroy(25);
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml b/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml
index 4847fc9196..ad88f1c58c 100644
--- a/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml
+++ b/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml
@@ -2,5 +2,5 @@ import Things 1.0
Something {
property var a: SomethingEntirelyStrange {}
- property var b: SomethingEntirelyStrange.AAA
+ property var b: SomethingEntirelyStrange.AnEnum.AAA
}
diff --git a/tests/auto/qml/qmllint/data/returnTypeAnnotation_component.qml b/tests/auto/qml/qmllint/data/returnTypeAnnotation_component.qml
new file mode 100644
index 0000000000..de142337b4
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/returnTypeAnnotation_component.qml
@@ -0,0 +1,9 @@
+import QtQml
+import QtQuick
+
+QtObject {
+ id: root
+ component Comp : Item { }
+ property Comp c: Comp{ }
+ function comp() { return root.c }
+}
diff --git a/tests/auto/qml/qmllint/data/returnTypeAnnotation_enum.qml b/tests/auto/qml/qmllint/data/returnTypeAnnotation_enum.qml
new file mode 100644
index 0000000000..0585ceceb2
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/returnTypeAnnotation_enum.qml
@@ -0,0 +1,5 @@
+import QtQuick
+
+QtObject {
+ function enumeration() { return Text.AlignRight }
+}
diff --git a/tests/auto/qml/qmllint/data/returnTypeAnnotation_method.qml b/tests/auto/qml/qmllint/data/returnTypeAnnotation_method.qml
new file mode 100644
index 0000000000..dc03311e73
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/returnTypeAnnotation_method.qml
@@ -0,0 +1,6 @@
+import QtQml
+
+QtObject {
+ function f() { }
+ function method() { return f }
+}
diff --git a/tests/auto/qml/qmllint/data/returnTypeAnnotation_property.qml b/tests/auto/qml/qmllint/data/returnTypeAnnotation_property.qml
new file mode 100644
index 0000000000..bb79978d85
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/returnTypeAnnotation_property.qml
@@ -0,0 +1,7 @@
+import QtQml
+
+QtObject {
+ id: root
+ property int i: 1
+ function prop() { return root.i }
+}
diff --git a/tests/auto/qml/qmllint/data/returnTypeAnnotation_type.qml b/tests/auto/qml/qmllint/data/returnTypeAnnotation_type.qml
new file mode 100644
index 0000000000..78f02a8b67
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/returnTypeAnnotation_type.qml
@@ -0,0 +1,5 @@
+import QtQml
+
+QtObject {
+ function type() { return 1 + 1 }
+}
diff --git a/tests/auto/qml/qmllint/data/scriptInTemplate.qml b/tests/auto/qml/qmllint/data/scriptInTemplate.qml
new file mode 100644
index 0000000000..ba333dcd3e
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/scriptInTemplate.qml
@@ -0,0 +1,6 @@
+import QtQml
+import scripts
+
+QtObject {
+ objectName: `Result: ${Foo.getText()}`
+}
diff --git a/tests/auto/qml/qmllint/data/scripts/Foo.js b/tests/auto/qml/qmllint/data/scripts/Foo.js
new file mode 100644
index 0000000000..1d5106f733
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/scripts/Foo.js
@@ -0,0 +1,6 @@
+.pragma library
+
+function getText() {
+ return "whohoooooo"
+}
+
diff --git a/tests/auto/qml/qmllint/data/scripts/qmldir b/tests/auto/qml/qmllint/data/scripts/qmldir
new file mode 100644
index 0000000000..b4bf844348
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/scripts/qmldir
@@ -0,0 +1,4 @@
+module scripts
+typeinfo scripts.qmltypes
+Foo 1.0 Foo.js
+
diff --git a/tests/auto/qml/qmllint/data/scripts/scripts.qmltypes b/tests/auto/qml/qmllint/data/scripts/scripts.qmltypes
new file mode 100644
index 0000000000..ebbfc41eb2
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/scripts/scripts.qmltypes
@@ -0,0 +1,22 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by qmltyperegistrar.
+
+Module {
+ Component {
+ file: "value.h"
+ name: "ValueType"
+ accessSemantics: "value"
+ exports: ["scripts/vvv 1.0"]
+ exportMetaObjectRevisions: [256]
+ Method {
+ name: "ValueType"
+ isConstructor: true
+ Parameter { name: "v"; type: "QString" }
+ }
+ Method { name: "ValueType"; isCloned: true; isConstructor: true }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/scriptstring.qml b/tests/auto/qml/qmllint/data/scriptstring.qml
new file mode 100644
index 0000000000..733434e924
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/scriptstring.qml
@@ -0,0 +1,73 @@
+import QtQuick
+
+Window {
+ id: root
+
+ Rectangle {
+ id: main
+
+ MouseArea {
+ id: mouse
+ property int clickCount: 0
+ onClicked: {
+ clickCount++
+
+ switch ( clickCount % 3 ) {
+ case 1 :
+ main.state = "middleState"
+ break
+ case 2 :
+ main.state = "rightState"
+ break
+ default :
+ main.state = "leftState"
+ }
+ }
+ }
+
+ Rectangle {
+ id: mover
+ anchors {
+ left: undefined
+ right: undefined
+ horizontalCenter: undefined
+ top: main.top
+ bottom: main.bottom
+ }
+ }
+
+ states: [
+ State {
+ name: "leftState"
+ AnchorChanges {
+ target: mover
+ anchors.left: main.left
+ anchors.right: undefined
+ anchors.horizontalCenter: undefined
+ }
+ },
+ State {
+ name: "middleState"
+ AnchorChanges {
+ target: mover
+ anchors {
+ left: undefined
+ right: undefined
+ horizontalCenter: main.horizontalCenter
+ }
+ }
+ },
+ State {
+ name: "rightState"
+ AnchorChanges {
+ target: mover
+ anchors {
+ left: undefined
+ right: main.right
+ horizontalCenter: undefined
+ }
+ }
+ }
+ ]
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/settings/plugin/.qmllint.ini b/tests/auto/qml/qmllint/data/settings/plugin/.qmllint.ini
new file mode 100644
index 0000000000..a72e0e29e2
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/settings/plugin/.qmllint.ini
@@ -0,0 +1,2 @@
+[Warnings]
+TestWarning=disable
diff --git a/tests/auto/qml/qmllint/data/settings/plugin/elemenpass_pluginSettingTest.qml b/tests/auto/qml/qmllint/data/settings/plugin/elemenpass_pluginSettingTest.qml
new file mode 100644
index 0000000000..b9250a2d11
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/settings/plugin/elemenpass_pluginSettingTest.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Item {
+ Rectangle {
+ radius: 5
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/something.qml b/tests/auto/qml/qmllint/data/something.qml
new file mode 100644
index 0000000000..38998f606d
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/something.qml
@@ -0,0 +1,2 @@
+import ModuleInImportPath
+A {}
diff --git a/tests/auto/qml/qmllint/data/storeNameMethod.qml b/tests/auto/qml/qmllint/data/storeNameMethod.qml
new file mode 100644
index 0000000000..fca02b288f
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/storeNameMethod.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+
+Window {
+ Rectangle {
+
+ Timer {
+ function foo() {}
+ onTriggered: foo = 1
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/stringToDateTime.qml b/tests/auto/qml/qmllint/data/stringToDateTime.qml
new file mode 100644
index 0000000000..dc4bd6cda5
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/stringToDateTime.qml
@@ -0,0 +1,7 @@
+import StringToDateTime
+
+StringToDateTime {
+ aDate: "2023-03-29"
+ aTime: "15:10:41"
+ aDateTime: "2023-03-29 15:10:41"
+}
diff --git a/tests/auto/qml/qmllint/data/untitled/components/Foo.qml b/tests/auto/qml/qmllint/data/untitled/components/Foo.qml
new file mode 100644
index 0000000000..10e5741900
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/untitled/components/Foo.qml
@@ -0,0 +1,5 @@
+import QtQuick
+
+Text {
+ text: "Here I am!"
+}
diff --git a/tests/auto/qml/qmllint/data/untitled/main.qml b/tests/auto/qml/qmllint/data/untitled/main.qml
new file mode 100644
index 0000000000..cf8980ab55
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/untitled/main.qml
@@ -0,0 +1,9 @@
+pragma Strict
+
+import QtQuick
+import 'qrc:/untitled/components' as C
+
+Window {
+ id: root
+ C.Foo {}
+}
diff --git a/tests/auto/qml/qmllint/data/untitled/qrcUrlImport.qrc b/tests/auto/qml/qmllint/data/untitled/qrcUrlImport.qrc
new file mode 100644
index 0000000000..0ad0d57fbb
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/untitled/qrcUrlImport.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/untitled/">
+ <file alias="main.qml">main.qml</file>
+ <file alias="components/Foo.qml">components/Foo.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/qml/qmllint/data/useConstInvokable.qml b/tests/auto/qml/qmllint/data/useConstInvokable.qml
new file mode 100644
index 0000000000..4f89e89918
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/useConstInvokable.qml
@@ -0,0 +1,5 @@
+import Things
+
+ConstInvokable {
+ objectName: getObject().objectName
+}
diff --git a/tests/auto/qml/qmllint/data/validLiterals.qml b/tests/auto/qml/qmllint/data/validLiterals.qml
index 4f8c575cd3..55792eaae2 100644
--- a/tests/auto/qml/qmllint/data/validLiterals.qml
+++ b/tests/auto/qml/qmllint/data/validLiterals.qml
@@ -29,9 +29,9 @@ QtObject {
property date date1: "2021-08-13T14:16:21.435Z"
- property point point1: "1,2"
+ property point point1: ({ x: 1, y: 2 })
- property size size1: "50x50"
+ property size size1: ({ width: 50, height: 50 })
- property rect rect1: "10,20,30x30"
+ property rect rect1: ({ x: 10, y: 20, width: 30, height: 30 })
}
diff --git a/tests/auto/qml/qmllint/data/valueTypesFromString.qml b/tests/auto/qml/qmllint/data/valueTypesFromString.qml
new file mode 100644
index 0000000000..fc013f858f
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/valueTypesFromString.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Item {
+ property point p: "30,50"
+ property rect p3: "10, 20, 30x50"
+ property size p4: "30x50"
+}
diff --git a/tests/auto/qml/qmllint/data/variantMapLookup.qml b/tests/auto/qml/qmllint/data/variantMapLookup.qml
new file mode 100644
index 0000000000..7f50879932
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/variantMapLookup.qml
@@ -0,0 +1,13 @@
+pragma Strict
+import TestTypes
+import QtQuick
+
+Item {
+ VariantMapLookupFoo {
+ id: moo
+ }
+ Component.onCompleted: {
+ moo.data.value = 5
+ moo.data["value"] = 6
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/writeListProperty.qml b/tests/auto/qml/qmllint/data/writeListProperty.qml
new file mode 100644
index 0000000000..8015fdf51b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/writeListProperty.qml
@@ -0,0 +1,7 @@
+import QtQuick
+
+Item {
+ id: self
+ property Item a: Item { id: a }
+ Component.onCompleted: self.data = [ a ]
+}
diff --git a/tests/auto/qml/qmllint/lintplugin.cpp b/tests/auto/qml/qmllint/lintplugin.cpp
index 47279adcaa..58b174cb6b 100644
--- a/tests/auto/qml/qmllint/lintplugin.cpp
+++ b/tests/auto/qml/qmllint/lintplugin.cpp
@@ -1,11 +1,11 @@
// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "lintplugin.h"
using namespace Qt::StringLiterals;
-static constexpr LoggerWarningId plugin { "testPlugin.test" };
+static constexpr QQmlSA::LoggerWarningId plugin{ "testPlugin.test" };
class ElementTest : public QQmlSA::ElementPass
{
@@ -17,25 +17,25 @@ public:
bool shouldRun(const QQmlSA::Element &element) override
{
- return element->baseType() == m_rectangle;
+ return element.baseType() == m_rectangle;
}
void run(const QQmlSA::Element &element) override
{
- auto property = element->property(u"radius"_s);
- if (!property.isValid() || element->property(u"radius"_s).typeName() != u"double") {
- emitWarning(u"Failed to verify radius property", plugin, element->sourceLocation());
+ auto property = element.property(u"radius"_s);
+ if (!property.isValid() || element.property(u"radius"_s).typeName() != u"double") {
+ emitWarning(u"Failed to verify radius property", plugin, element.sourceLocation());
return;
}
- auto bindings = element->propertyBindings(u"radius"_s);
+ auto bindings = element.propertyBindings(u"radius"_s);
if (bindings.isEmpty() || bindings.constFirst().numberValue() != 5) {
emitWarning(u"Failed to verify radius property binding", plugin,
- element->sourceLocation());
+ element.sourceLocation());
return;
}
- emitWarning(u"ElementTest OK", plugin, element->sourceLocation());
+ emitWarning(u"ElementTest OK", plugin, element.sourceLocation());
}
private:
@@ -48,37 +48,37 @@ public:
PropertyTest(QQmlSA::PassManager *manager) : QQmlSA::PropertyPass(manager) { }
void onBinding(const QQmlSA::Element &element, const QString &propertyName,
- const QQmlJSMetaPropertyBinding &binding, const QQmlSA::Element &bindingScope,
+ const QQmlSA::Binding &binding, const QQmlSA::Element &bindingScope,
const QQmlSA::Element &value) override
{
emitWarning(u"Saw binding on %1 property %2 with value %3 (and type %4) in scope %5"_s
- .arg(element->baseTypeName(), propertyName,
+ .arg(element.baseTypeName(), propertyName,
value.isNull()
? u"NULL"_s
- : (value->internalName().isNull() ? value->baseTypeName()
- : value->baseTypeName()))
- .arg(binding.bindingType())
- .arg(bindingScope->baseTypeName()),
- plugin, bindingScope->sourceLocation());
+ : (value.name().isNull() ? value.baseTypeName()
+ : value.name()))
+ .arg(qToUnderlying(binding.bindingType()))
+ .arg(bindingScope.baseTypeName()),
+ plugin, bindingScope.sourceLocation());
}
void onRead(const QQmlSA::Element &element, const QString &propertyName,
- const QQmlSA::Element &readScope, QQmlJS::SourceLocation location) override
+ const QQmlSA::Element &readScope, QQmlSA::SourceLocation location) override
{
emitWarning(u"Saw read on %1 property %2 in scope %3"_s.arg(
- element->baseTypeName(), propertyName, readScope->baseTypeName()),
+ element.baseTypeName(), propertyName, readScope.baseTypeName()),
plugin, location);
}
void onWrite(const QQmlSA::Element &element, const QString &propertyName,
const QQmlSA::Element &value, const QQmlSA::Element &writeScope,
- QQmlJS::SourceLocation location) override
+ QQmlSA::SourceLocation location) override
{
emitWarning(u"Saw write on %1 property %2 with value %3 in scope %4"_s.arg(
- element->baseTypeName(), propertyName,
- (value->internalName().isNull() ? value->baseTypeName()
- : value->internalName()),
- writeScope->baseTypeName()),
+ element.baseTypeName(), propertyName,
+ (value.name().isNull() ? value.baseTypeName()
+ : value.name()),
+ writeScope.baseTypeName()),
plugin, location);
}
};
@@ -109,7 +109,7 @@ private:
void LintPlugin::registerPasses(QQmlSA::PassManager *manager, const QQmlSA::Element &rootElement)
{
- if (!rootElement->filePath().endsWith(u"_pluginTest.qml"))
+ if (!rootElement.filePath().endsWith(u"_pluginTest.qml"))
return;
manager->registerElementPass(std::make_unique<ElementTest>(manager));
diff --git a/tests/auto/qml/qmllint/lintplugin.h b/tests/auto/qml/qmllint/lintplugin.h
index 76733ca7a7..c121657456 100644
--- a/tests/auto/qml/qmllint/lintplugin.h
+++ b/tests/auto/qml/qmllint/lintplugin.h
@@ -1,12 +1,12 @@
// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef LINTPLUGIN_H
#define LINTPLUGIN_H
#include <QtPlugin>
#include <QtCore/qobject.h>
-#include <QtQmlCompiler/private/qqmlsa_p.h>
+#include <QtQmlCompiler/qqmlsa.h>
class LintPlugin : public QObject, public QQmlSA::LintPlugin
{
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index a5e906ce9a..7f7b5317cc 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -1,6 +1,6 @@
// Copyright (C) 2016 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Sergio Martins <sergio.martins@kdab.com>
// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtTest/QtTest>
#include <QProcess>
@@ -43,6 +43,11 @@ public:
Flags flags = {};
};
+ struct Environment : public QList<QPair<QString, QString>>
+ {
+ using QList<QPair<QString, QString>>::QList;
+ };
+
private Q_SLOTS:
void initTestCase() override;
@@ -73,12 +78,19 @@ private Q_SLOTS:
void autoqmltypes();
void resources();
+ void multiDirectory();
+
void requiredProperty();
void settingsFile();
void additionalImplicitImport();
+ void qrcUrlImport();
+
+ void incorrectImportFromHost_data();
+ void incorrectImportFromHost();
+
void attachedPropertyReuse();
void missingBuiltinsNoCrash();
@@ -90,11 +102,21 @@ private Q_SLOTS:
void lintModule();
void testLineEndings();
+ void valueTypesFromString();
+
+ void ignoreSettingsNotCommandLineOptions();
+ void backslashedQmldirPath();
+
+ void environment_data();
+ void environment();
+
+ void maxWarnings();
#if QT_CONFIG(library)
void testPlugin();
void quickPlugin();
#endif
+
private:
enum DefaultImportOption { NoDefaultImports, UseDefaultImports };
enum ContainOption { StringNotContained, StringContained };
@@ -105,17 +127,24 @@ private:
enum LintType { LintFile, LintModule };
+ static QStringList warningsShouldFailArgs() {
+ static QStringList args {"-W", "0"};
+ return args;
+ }
+
QString runQmllint(const QString &fileToLint, std::function<void(QProcess &)> handleResult,
const QStringList &extraArgs = QStringList(), bool ignoreSettings = true,
- bool addImportDirs = true, bool absolutePath = true);
+ bool addImportDirs = true, bool absolutePath = true,
+ const Environment &env = {});
QString runQmllint(const QString &fileToLint, bool shouldSucceed,
const QStringList &extraArgs = QStringList(), bool ignoreSettings = true,
- bool addImportDirs = true, bool absolutePath = true);
+ bool addImportDirs = true, bool absolutePath = true,
+ const Environment &env = {});
void callQmllint(const QString &fileToLint, bool shouldSucceed, QJsonArray *warnings = nullptr,
QStringList importDirs = {}, QStringList qmltypesFiles = {},
QStringList resources = {},
DefaultImportOption defaultImports = UseDefaultImports,
- QList<QQmlJSLogger::Category> *categories = nullptr, bool autoFixable = false,
+ QList<QQmlJS::LoggerCategory> *categories = nullptr, bool autoFixable = false,
LintType type = LintFile);
void searchWarnings(const QJsonArray &warnings, const QString &string,
@@ -137,7 +166,7 @@ private:
void runTest(const QString &testFile, const Result &result, QStringList importDirs = {},
QStringList qmltypesFiles = {}, QStringList resources = {},
DefaultImportOption defaultImports = UseDefaultImports,
- QList<QQmlJSLogger::Category> *categories = nullptr);
+ QList<QQmlJS::LoggerCategory> *categories = nullptr);
QString m_qmllintPath;
QString m_qmljsrootgenPath;
@@ -258,6 +287,12 @@ void TestQmllint::testUnqualified_data()
Message {
QStringLiteral("index is implicitly injected into this delegate. "
"Add a required property instead.") } } };
+ QTest::newRow("storeSloppy")
+ << QStringLiteral("UnqualifiedInStoreSloppy.qml")
+ << Result{ { Message{ QStringLiteral("Unqualified access"), 9, 26} } };
+ QTest::newRow("storeStrict")
+ << QStringLiteral("UnqualifiedInStoreStrict.qml")
+ << Result{ { Message{ QStringLiteral("Unqualified access"), 9, 52} } };
}
void TestQmllint::testUnknownCausesFail()
@@ -355,12 +390,12 @@ void TestQmllint::verifyJsRoot()
QString currentJsRootContent, generatedJsRootContent;
QFile currentJsRoot(currentJsRootPath);
- QVERIFY(currentJsRoot.open(QFile::ReadOnly));
+ QVERIFY(currentJsRoot.open(QFile::ReadOnly | QIODevice::Text));
currentJsRootContent = QString::fromUtf8(currentJsRoot.readAll());
currentJsRoot.close();
QFile generatedJsRoot(dir.path() + QDir::separator() + "jsroot.qmltypes");
- QVERIFY(generatedJsRoot.open(QFile::ReadOnly));
+ QVERIFY(generatedJsRoot.open(QFile::ReadOnly | QIODevice::Text));
generatedJsRootContent = QString::fromUtf8(generatedJsRoot.readAll());
generatedJsRoot.close();
@@ -383,7 +418,7 @@ void TestQmllint::autoqmltypes()
{
QProcess process;
process.setWorkingDirectory(testFile("autoqmltypes"));
- process.start(m_qmllintPath, { QStringLiteral("test.qml") });
+ process.start(m_qmllintPath, warningsShouldFailArgs() << QStringLiteral("test.qml") );
process.waitForFinished();
@@ -393,6 +428,21 @@ void TestQmllint::autoqmltypes()
QVERIFY(process.readAllStandardError()
.contains("is not a qmldir file. Assuming qmltypes"));
QVERIFY(process.readAllStandardOutput().isEmpty());
+
+ {
+ QProcess bare;
+ bare.setWorkingDirectory(testFile("autoqmltypes"));
+ bare.start(m_qmllintPath, warningsShouldFailArgs() << QStringLiteral("--bare") << QStringLiteral("test.qml") );
+ bare.waitForFinished();
+
+ const QByteArray errors = bare.readAllStandardError();
+ QVERIFY(!errors.contains("is not a qmldir file. Assuming qmltypes"));
+ QVERIFY(errors.contains("Failed to import TestTest."));
+ QVERIFY(bare.readAllStandardOutput().isEmpty());
+
+ QCOMPARE(bare.exitStatus(), QProcess::NormalExit);
+ QVERIFY(bare.exitCode() != 0);
+ }
}
void TestQmllint::resources()
@@ -422,6 +472,17 @@ void TestQmllint::resources()
}
}
+void TestQmllint::multiDirectory()
+{
+ callQmllint(
+ testFile("MultiDirectory/qml/Inner.qml"), true, nullptr,
+ {}, {}, { testFile("MultiDirectory/multi.qrc") });
+
+ callQmllint(
+ testFile("MultiDirectory/qml/pages/Page.qml"), true, nullptr,
+ {}, {}, { testFile("MultiDirectory/multi.qrc") });
+}
+
void TestQmllint::dirtyQmlCode_data()
{
QTest::addColumn<QString>("filename");
@@ -444,12 +505,12 @@ void TestQmllint::dirtyQmlCode_data()
QTest::newRow("MemberNotFound")
<< QStringLiteral("memberNotFound.qml")
<< Result { { Message {
- QStringLiteral("Property \"foo\" not found on type \"QtObject\""), 6,
+ QStringLiteral("Member \"foo\" not found on type \"QtObject\""), 6,
31 } } };
QTest::newRow("UnknownJavascriptMethd")
<< QStringLiteral("unknownJavascriptMethod.qml")
<< Result { { Message {
- QStringLiteral("Property \"foo2\" not found on type \"Methods\""), 5,
+ QStringLiteral("Member \"foo2\" not found on type \"Methods\""), 5,
25 } } };
QTest::newRow("badAlias")
<< QStringLiteral("badAlias.qml")
@@ -463,6 +524,12 @@ void TestQmllint::dirtyQmlCode_data()
QStringLiteral("Invalid alias expression. Only IDs and field member "
"expressions can be aliased"),
5, 26 } } };
+ QTest::newRow("badAliasNotAnExpression")
+ << QStringLiteral("badAliasNotAnExpression.qml")
+ << Result { { Message {
+ QStringLiteral("Invalid alias expression. Only IDs and field member "
+ "expressions can be aliased"),
+ 4, 30 } } };
QTest::newRow("aliasCycle1") << QStringLiteral("aliasCycle.qml")
<< Result { { Message {
QStringLiteral("Alias \"b\" is part of an alias cycle"),
@@ -485,17 +552,17 @@ void TestQmllint::dirtyQmlCode_data()
9, 34 } } };
QTest::newRow("badParent")
<< QStringLiteral("badParent.qml")
- << Result { { Message { QStringLiteral("Property \"rrr\" not found on type \"Item\""),
+ << Result { { Message { QStringLiteral("Member \"rrr\" not found on type \"Item\""),
5, 34 } } };
QTest::newRow("parentIsComponent")
<< QStringLiteral("parentIsComponent.qml")
<< Result { { Message {
- QStringLiteral("Property \"progress\" not found on type \"QQuickItem\""), 7,
+ QStringLiteral("Member \"progress\" not found on type \"QQuickItem\""), 7,
39 } } };
QTest::newRow("badTypeAssertion")
<< QStringLiteral("badTypeAssertion.qml")
<< Result { { Message {
- QStringLiteral("Property \"rrr\" not found on type \"QQuickItem\""), 5,
+ QStringLiteral("Member \"rrr\" not found on type \"QQuickItem\""), 5,
39 } } };
QTest::newRow("incompleteQmltypes")
<< QStringLiteral("incompleteQmltypes.qml")
@@ -504,7 +571,7 @@ void TestQmllint::dirtyQmlCode_data()
26 } } };
QTest::newRow("incompleteQmltypes2")
<< QStringLiteral("incompleteQmltypes2.qml")
- << Result { { Message { QStringLiteral("Property \"weDontKnowIt\" "
+ << Result { { Message { QStringLiteral("Member \"weDontKnowIt\" "
"not found on type \"CustomPalette\""),
5, 35 } } };
QTest::newRow("incompleteQmltypes3")
@@ -526,11 +593,11 @@ void TestQmllint::dirtyQmlCode_data()
QTest::newRow("javascriptMethodsInModule")
<< QStringLiteral("javascriptMethodsInModuleBad.qml")
<< Result { { Message {
- QStringLiteral("Property \"unknownFunc\" not found on type \"Foo\""), 5,
+ QStringLiteral("Member \"unknownFunc\" not found on type \"Foo\""), 5,
21 } } };
QTest::newRow("badEnumFromQtQml")
<< QStringLiteral("badEnumFromQtQml.qml")
- << Result { { Message { QStringLiteral("Property \"Linear123\" not "
+ << Result { { Message { QStringLiteral("Member \"Linear123\" not "
"found on type \"QQmlEasingEnums\""),
4, 30 } } };
QTest::newRow("anchors3")
@@ -548,13 +615,13 @@ void TestQmllint::dirtyQmlCode_data()
"unknown grouped property scope nanchors.") } } };
QTest::newRow("badAliasObject")
<< QStringLiteral("badAliasObject.qml")
- << Result { { Message { QStringLiteral("Property \"wrongwrongwrong\" not "
+ << Result { { Message { QStringLiteral("Member \"wrongwrongwrong\" not "
"found on type \"QtObject\""),
8, 40 } } };
QTest::newRow("badScript") << QStringLiteral("badScript.qml")
<< Result { { Message {
QStringLiteral(
- "Property \"stuff\" not found on type \"Empty\""),
+ "Member \"stuff\" not found on type \"Empty\""),
5, 21 } } };
QTest::newRow("badScriptOnAttachedProperty")
<< QStringLiteral("badScript.attached.qml")
@@ -565,7 +632,7 @@ void TestQmllint::dirtyQmlCode_data()
QTest::newRow("segFault (bad)")
<< QStringLiteral("SegFault.bad.qml")
<< Result { { Message { QStringLiteral(
- "Property \"foobar\" not found on type \"QQuickScreenAttached\"") } } };
+ "Member \"foobar\" not found on type \"QQuickScreenAttached\"") } } };
QTest::newRow("VariableUsedBeforeDeclaration")
<< QStringLiteral("useBeforeDeclaration.qml")
<< Result { { Message {
@@ -585,7 +652,7 @@ void TestQmllint::dirtyQmlCode_data()
"than the signal it handles.") } } };
QTest::newRow("OnAssignment") << QStringLiteral("onAssignment.qml")
<< Result { { Message { QStringLiteral(
- "Property \"loops\" not found on type \"bool\"") } } };
+ "Member \"loops\" not found on type \"bool\"") } } };
QTest::newRow("BadAttached") << QStringLiteral("badAttached.qml")
<< Result { { Message { QStringLiteral(
"unknown attached property scope WrongAttached.") } } };
@@ -702,13 +769,13 @@ void TestQmllint::dirtyQmlCode_data()
QTest::newRow("badAttachedProperty")
<< QStringLiteral("badAttachedProperty.qml")
<< Result { { Message {
- QStringLiteral("Property \"progress\" not found on type \"TestType\"") } } };
+ QStringLiteral("Member \"progress\" not found on type \"TestType\"") } } };
QTest::newRow("badAttachedPropertyNested")
<< QStringLiteral("badAttachedPropertyNested.qml")
<< Result { { Message { QStringLiteral(
- "Property \"progress\" not found on type \"QObject\""),
+ "Member \"progress\" not found on type \"QObject\""),
12, 41 } },
- { Message { QString("Property \"progress\" not found on type \"QObject\""),
+ { Message { QString("Member \"progress\" not found on type \"QObject\""),
6, 37 } } };
QTest::newRow("badAttachedPropertyTypeString")
<< QStringLiteral("badAttachedPropertyTypeString.qml")
@@ -780,6 +847,14 @@ singleTicks: ' \\' \\\\'
expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
16, 27 } },
{ Result::ExitsNormally, Result::AutoFixable } };
+ QTest::addRow("multifix")
+ << QStringLiteral("multifix.qml")
+ << Result { {
+ Message { QStringLiteral("Unqualified access"), 7, 19, QtWarningMsg},
+ Message { QStringLiteral("Unqualified access"), 11, 19, QtWarningMsg},
+ }, {}, {
+ Message { QStringLiteral("pragma ComponentBehavior: Bound\n"), 1, 1 }
+ }, { Result::AutoFixable }};
QTest::newRow("unresolvedType")
<< QStringLiteral("unresolvedType.qml")
<< Result { { Message { QStringLiteral(
@@ -812,7 +887,7 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("QtQuick.Window 2.0")
<< QStringLiteral("qtquickWindow20.qml")
<< Result { { Message { QStringLiteral(
- "Property \"window\" not found on type \"QQuickWindow\"") } } };
+ "Member \"window\" not found on type \"QQuickWindow\"") } } };
QTest::newRow("unresolvedAttachedType")
<< QStringLiteral("unresolvedAttachedType.qml")
<< Result { { Message { QStringLiteral(
@@ -879,22 +954,22 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("enumInvalid")
<< QStringLiteral("enumInvalid.qml")
<< Result { { Message {
- QStringLiteral("Property \"red\" not found on type \"QtObject\"") } } };
+ QStringLiteral("Member \"red\" not found on type \"QtObject\"") } } };
QTest::newRow("inaccessibleId")
<< QStringLiteral("inaccessibleId.qml")
<< Result { { Message {
- QStringLiteral("Property \"objectName\" not found on type \"int\"") } } };
+ QStringLiteral("Member \"objectName\" not found on type \"int\"") } } };
QTest::newRow("inaccessibleId2")
<< QStringLiteral("inaccessibleId2.qml")
<< Result { { Message {
- QStringLiteral("Property \"objectName\" not found on type \"int\"") } } };
+ QStringLiteral("Member \"objectName\" not found on type \"int\"") } } };
QTest::newRow("unknownTypeCustomParser")
<< QStringLiteral("unknownTypeCustomParser.qml")
<< Result { { Message { QStringLiteral("TypeDoesNotExist was not found.") } } };
QTest::newRow("nonNullStored")
<< QStringLiteral("nonNullStored.qml")
<< Result { { Message { QStringLiteral(
- "Property \"objectName\" not found on type \"Foozle\"") } },
+ "Member \"objectName\" not found on type \"Foozle\"") } },
{ Message { QStringLiteral("Unqualified access") } } };
QTest::newRow("cppPropertyChangeHandlers-wrong-parameters-size-bindable")
<< QStringLiteral("badCppPropertyChangeHandlers1.qml")
@@ -936,13 +1011,13 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("didYouMean(property)")
<< QStringLiteral("didYouMeanProperty.qml")
<< Result { { Message { QStringLiteral(
- "Property \"hoight\" not found on type \"Rectangle\"") },
+ "Member \"hoight\" not found on type \"Rectangle\"") },
{},
{ Message { QStringLiteral("height") } } } };
QTest::newRow("didYouMean(propertyCall)")
<< QStringLiteral("didYouMeanPropertyCall.qml")
<< Result {
- { Message { QStringLiteral("Property \"lgg\" not found on type \"Console\"") },
+ { Message { QStringLiteral("Member \"lgg\" not found on type \"Console\"") },
{},
{ Message { QStringLiteral("log") } } }
};
@@ -955,7 +1030,7 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("didYouMean(enum)")
<< QStringLiteral("didYouMeanEnum.qml")
<< Result { { Message { QStringLiteral(
- "Property \"Readx\" not found on type \"QQuickImage\"") },
+ "Member \"Readx\" not found on type \"QQuickImage\"") },
{},
{ Message { QStringLiteral("Ready") } } } };
QTest::newRow("nullBinding") << QStringLiteral("nullBinding.qml")
@@ -1020,9 +1095,8 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
QTest::newRow("NotScopedEnumCpp")
<< QStringLiteral("NotScopedEnumCpp.qml")
<< Result{ { Message{
- QStringLiteral(
- "Type is an unscoped enum. You cannot access \"V1\" from here."),
- 5, 57 } } };
+ QStringLiteral("You cannot access unscoped enum \"TheEnum\" from here."), 5,
+ 49 } } };
QTest::newRow("unresolvedArrayBinding")
<< QStringLiteral("unresolvedArrayBinding.qml")
@@ -1044,6 +1118,56 @@ expression: \${expr} \${expr} \\\${expr} \\\${expr}`)",
"in nested components."), 0, 0, QtInfoMsg } },
Result::AutoFixable
};
+ QTest::newRow("IsNotAnEntryOfEnum")
+ << QStringLiteral("IsNotAnEntryOfEnum.qml")
+ << Result{ {
+ Message {
+ QStringLiteral("Member \"Mode\" not found on type \"Item\""), 12,
+ 29, QtWarningMsg },
+ Message{
+ QStringLiteral("\"Hour\" is not an entry of enum \"Mode\"."), 13,
+ 62, QtInfoMsg }
+ },
+ {},
+ { Message{ QStringLiteral("Hours") } }
+ };
+
+ QTest::newRow("StoreNameMethod")
+ << QStringLiteral("storeNameMethod.qml")
+ << Result { { Message { QStringLiteral("Cannot assign to method foo") } } };
+
+ QTest::newRow("CoerceToVoid")
+ << QStringLiteral("coercetovoid.qml")
+ << Result { { Message {
+ QStringLiteral("Function without return type annotation returns double")
+ } } };
+
+ QTest::newRow("lowerCaseQualifiedImport")
+ << QStringLiteral("lowerCaseQualifiedImport.qml")
+ << Result{ {
+ Message{ u"Import qualifier 'test' must start with a capital letter."_s },
+ Message{
+ u"Namespace 'test' of 'test.Rectangle' must start with an upper case letter."_s },
+ } };
+ QTest::newRow("lowerCaseQualifiedImport2")
+ << QStringLiteral("lowerCaseQualifiedImport2.qml")
+ << Result{ {
+ Message{ u"Import qualifier 'test' must start with a capital letter."_s },
+ Message{
+ u"Namespace 'test' of 'test.Item' must start with an upper case letter."_s },
+ Message{
+ u"Namespace 'test' of 'test.Rectangle' must start with an upper case letter."_s },
+ Message{
+ u"Namespace 'test' of 'test.color' must start with an upper case letter."_s },
+ Message{
+ u"Namespace 'test' of 'test.Grid' must start with an upper case letter."_s },
+ } };
+ QTest::newRow("notQmlRootMethods")
+ << QStringLiteral("notQmlRootMethods.qml")
+ << Result{ {
+ Message{ u"Member \"deleteLater\" not found on type \"QtObject\""_s },
+ Message{ u"Member \"destroyed\" not found on type \"QtObject\""_s },
+ } };
}
void TestQmllint::dirtyQmlCode()
@@ -1167,6 +1291,7 @@ void TestQmllint::cleanQmlCode_data()
QTest::newRow("QVariant") << QStringLiteral("qvariant.qml");
QTest::newRow("Accessible") << QStringLiteral("accessible.qml");
QTest::newRow("qjsroot") << QStringLiteral("qjsroot.qml");
+ QTest::newRow("qmlRootMethods") << QStringLiteral("qmlRootMethods.qml");
QTest::newRow("InlineComponent") << QStringLiteral("inlineComponent.qml");
QTest::newRow("InlineComponentWithComponents") << QStringLiteral("inlineComponentWithComponents.qml");
QTest::newRow("InlineComponentsChained") << QStringLiteral("inlineComponentsChained.qml");
@@ -1216,6 +1341,21 @@ void TestQmllint::cleanQmlCode_data()
QTest::newRow("propertyWithOn") << QStringLiteral("switcher.qml");
QTest::newRow("constructorProperty") << QStringLiteral("constructorProperty.qml");
QTest::newRow("onlyMajorVersion") << QStringLiteral("onlyMajorVersion.qml");
+ QTest::newRow("attachedImportUse") << QStringLiteral("attachedImportUse.qml");
+ QTest::newRow("VariantMapGetPropertyLookup") << QStringLiteral("variantMapLookup.qml");
+ QTest::newRow("StringToDateTime") << QStringLiteral("stringToDateTime.qml");
+ QTest::newRow("ScriptInTemplate") << QStringLiteral("scriptInTemplate.qml");
+ QTest::newRow("AddressableValue") << QStringLiteral("addressableValue.qml");
+ QTest::newRow("WriteListProperty") << QStringLiteral("writeListProperty.qml");
+ QTest::newRow("dontConfuseMemberPrintWithGlobalPrint") << QStringLiteral("findMemberPrint.qml");
+ QTest::newRow("groupedAttachedLayout") << QStringLiteral("groupedAttachedLayout.qml");
+ QTest::newRow("QQmlScriptString") << QStringLiteral("scriptstring.qml");
+ QTest::newRow("QEventPoint") << QStringLiteral("qEventPoint.qml");
+ QTest::newRow("locale") << QStringLiteral("locale.qml");
+ QTest::newRow("constInvokable") << QStringLiteral("useConstInvokable.qml");
+ QTest::newRow("dontCheckJSTypes") << QStringLiteral("dontCheckJSTypes.qml");
+ QTest::newRow("jsonObjectIsRecognized") << QStringLiteral("jsonObjectIsRecognized.qml");
+ QTest::newRow("jsonArrayIsRecognized") << QStringLiteral("jsonArrayIsRecognized.qml");
}
void TestQmllint::cleanQmlCode()
@@ -1239,10 +1379,10 @@ void TestQmllint::compilerWarnings_data()
QTest::newRow("qQmlV4Function") << QStringLiteral("varargs.qml") << Result::clean() << true;
QTest::newRow("multiGrouped") << QStringLiteral("multiGrouped.qml") << Result::clean() << true;
- QTest::newRow("shadowable") << QStringLiteral("shadowable.qml")
- << Result { { Message { QStringLiteral(
- "with type NotSoSimple can be shadowed") } } }
- << true;
+ QTest::newRow("shadowable")
+ << QStringLiteral("shadowable.qml")
+ << Result { { Message {QStringLiteral("with type NotSoSimple can be shadowed") } } }
+ << true;
QTest::newRow("tooFewParameters")
<< QStringLiteral("tooFewParams.qml")
<< Result { { Message { QStringLiteral("No matching override found") } } } << true;
@@ -1261,6 +1401,51 @@ void TestQmllint::compilerWarnings_data()
<< Result { { { QStringLiteral(
"Functions without type annotations won't be compiled") } } }
<< true;
+ QTest::newRow("generalizedGroupHint")
+ << QStringLiteral("generalizedGroupHint.qml")
+ << Result { { { QStringLiteral(
+ "Cannot resolve property type for binding on myColor. "
+ "You may want use ID-based grouped properties here.") } } }
+ << true;
+ QTest::newRow("invalidIdLookup")
+ << QStringLiteral("invalidIdLookup.qml")
+ << Result { { {
+ QStringLiteral("Cannot retrieve a non-object type by ID: stateMachine")
+ } } }
+ << true;
+ QTest::newRow("returnTypeAnnotation-component")
+ << QStringLiteral("returnTypeAnnotation_component.qml")
+ << Result{ { { "Could not compile function comp: function without return type "
+ "annotation returns (component in" },
+ { "returnTypeAnnotation_component.qml)::c with type Comp. "
+ "This may prevent proper compilation to Cpp." } } }
+ << true;
+ QTest::newRow("returnTypeAnnotation-enum")
+ << QStringLiteral("returnTypeAnnotation_enum.qml")
+ << Result{ { { "Could not compile function enumeration: function without return type "
+ "annotation returns QQuickText::HAlignment::AlignRight. "
+ "This may prevent proper compilation to Cpp." } } }
+ << true;
+ QTest::newRow("returnTypeAnnotation-method")
+ << QStringLiteral("returnTypeAnnotation_method.qml")
+ << Result{ { { "Could not compile function method: function without return type "
+ "annotation returns (component in " }, // Don't check the build folder path
+ { "returnTypeAnnotation_method.qml)::f(...). This may "
+ "prevent proper compilation to Cpp." } } }
+ << true;
+ QTest::newRow("returnTypeAnnotation-property")
+ << QStringLiteral("returnTypeAnnotation_property.qml")
+ << Result{ { { "Could not compile function prop: function without return type "
+ "annotation returns (component in " }, // Don't check the build folder path
+ { "returnTypeAnnotation_property.qml)::i with type int. This may prevent "
+ "proper compilation to Cpp." } } }
+ << true;
+ QTest::newRow("returnTypeAnnotation-type")
+ << QStringLiteral("returnTypeAnnotation_type.qml")
+ << Result{ { { "Could not compile function type: function without return type "
+ "annotation returns double. This may prevent proper compilation to "
+ "Cpp." } } }
+ << true;
}
void TestQmllint::compilerWarnings()
@@ -1273,11 +1458,15 @@ void TestQmllint::compilerWarnings()
auto categories = QQmlJSLogger::defaultCategories();
- auto category = std::find(categories.begin(), categories.end(), qmlCompiler);
+ auto category = std::find_if(categories.begin(), categories.end(), [](const QQmlJS::LoggerCategory& category) {
+ return category.id() == qmlCompiler;
+ });
Q_ASSERT(category != categories.end());
- if (enableCompilerWarnings)
- category->setLevel(u"warning"_s);
+ if (enableCompilerWarnings) {
+ category->setLevel(QtWarningMsg);
+ category->setIgnored(false);
+ }
runTest(filename, result, {}, {}, {}, UseDefaultImports, &categories);
}
@@ -1285,7 +1474,7 @@ void TestQmllint::compilerWarnings()
QString TestQmllint::runQmllint(const QString &fileToLint,
std::function<void(QProcess &)> handleResult,
const QStringList &extraArgs, bool ignoreSettings,
- bool addImportDirs, bool absolutePath)
+ bool addImportDirs, bool absolutePath, const Environment &env)
{
auto qmlImportDir = QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
QStringList args;
@@ -1311,6 +1500,11 @@ QString TestQmllint::runQmllint(const QString &fileToLint,
QString errors;
auto verify = [&](bool isSilent) {
QProcess process;
+ QProcessEnvironment processEnv = QProcessEnvironment::systemEnvironment();
+ for (const auto &entry : env)
+ processEnv.insert(entry.first, entry.second);
+
+ process.setProcessEnvironment(processEnv);
process.setWorkingDirectory(QFileInfo(absoluteFilePath).absolutePath());
process.start(m_qmllintPath, args);
handleResult(process);
@@ -1353,7 +1547,7 @@ QString TestQmllint::runQmllint(const QString &fileToLint,
QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed,
const QStringList &extraArgs, bool ignoreSettings,
- bool addImportDirs, bool absolutePath)
+ bool addImportDirs, bool absolutePath, const Environment &env)
{
return runQmllint(
fileToLint,
@@ -1366,13 +1560,13 @@ QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed,
else
QVERIFY(process.exitCode() != 0);
},
- extraArgs, ignoreSettings, addImportDirs, absolutePath);
+ extraArgs, ignoreSettings, addImportDirs, absolutePath, env);
}
void TestQmllint::callQmllint(const QString &fileToLint, bool shouldSucceed, QJsonArray *warnings,
QStringList importPaths, QStringList qmldirFiles,
QStringList resources, DefaultImportOption defaultImports,
- QList<QQmlJSLogger::Category> *categories, bool autoFixable,
+ QList<QQmlJS::LoggerCategory> *categories, bool autoFixable,
LintType type)
{
QJsonArray jsonOutput;
@@ -1382,18 +1576,22 @@ void TestQmllint::callQmllint(const QString &fileToLint, bool shouldSucceed, QJs
QQmlJSLinter::LintResult lintResult;
+ const QStringList resolvedImportPaths = defaultImports == UseDefaultImports
+ ? m_defaultImportPaths + importPaths
+ : importPaths;
if (type == LintFile) {
+ const QList<QQmlJS::LoggerCategory> resolvedCategories =
+ categories != nullptr ? *categories : QQmlJSLogger::defaultCategories();
lintResult = m_linter.lintFile(
- lintedFile, nullptr, true, &jsonOutput,
- defaultImports == UseDefaultImports ? m_defaultImportPaths + importPaths
- : importPaths,
- qmldirFiles, resources,
- categories != nullptr ? *categories : QQmlJSLogger::defaultCategories());
+ lintedFile, nullptr, true, &jsonOutput, resolvedImportPaths, qmldirFiles,
+ resources, resolvedCategories);
} else {
- lintResult = m_linter.lintModule(fileToLint, true, &jsonOutput);
+ lintResult =
+ m_linter.lintModule(fileToLint, true, &jsonOutput, resolvedImportPaths, resources);
}
bool success = lintResult == QQmlJSLinter::LintSuccess;
+ QEXPECT_FAIL("qtquickdialog", "Will fail until QTBUG-104091 is implemented", Abort);
QVERIFY2(success == shouldSucceed, QJsonDocument(jsonOutput).toJson());
if (warnings) {
@@ -1425,7 +1623,7 @@ void TestQmllint::callQmllint(const QString &fileToLint, bool shouldSucceed, QJs
if (QFileInfo(fixedPath).exists()) {
QFile fixedFile(fixedPath);
- fixedFile.open(QFile::ReadOnly);
+ QVERIFY(fixedFile.open(QFile::ReadOnly));
QString fixedFileContents = QString::fromUtf8(fixedFile.readAll());
#ifdef Q_OS_WIN
fixedCode = fixedCode.replace(u"\r\n"_s, u"\n"_s);
@@ -1447,7 +1645,7 @@ void TestQmllint::callQmllint(const QString &fileToLint, bool shouldSucceed, QJs
void TestQmllint::runTest(const QString &testFile, const Result &result, QStringList importDirs,
QStringList qmltypesFiles, QStringList resources,
DefaultImportOption defaultImports,
- QList<QQmlJSLogger::Category> *categories)
+ QList<QQmlJS::LoggerCategory> *categories)
{
QJsonArray warnings;
callQmllint(testFile, result.flags.testFlag(Result::Flag::ExitsNormally), &warnings, importDirs,
@@ -1604,17 +1802,17 @@ void TestQmllint::requiredProperty()
void TestQmllint::settingsFile()
{
- QVERIFY(runQmllint("settings/unqualifiedSilent/unqualified.qml", true, QStringList(), false)
+ QVERIFY(runQmllint("settings/unqualifiedSilent/unqualified.qml", true, warningsShouldFailArgs(), false)
.isEmpty());
- QVERIFY(runQmllint("settings/unusedImportWarning/unused.qml", false, QStringList(), false)
+ QVERIFY(runQmllint("settings/unusedImportWarning/unused.qml", false, warningsShouldFailArgs(), false)
.contains(QStringLiteral("Warning: %1:2:1: Unused import")
.arg(testFile("settings/unusedImportWarning/unused.qml"))));
- QVERIFY(runQmllint("settings/bare/bare.qml", false, {}, false, false)
+ QVERIFY(runQmllint("settings/bare/bare.qml", false, warningsShouldFailArgs(), false, false)
.contains(QStringLiteral("Failed to find the following builtins: "
- "builtins.qmltypes, jsroot.qmltypes")));
- QVERIFY(runQmllint("settings/qmltypes/qmltypes.qml", false, QStringList(), false)
+ "jsroot.qmltypes, builtins.qmltypes")));
+ QVERIFY(runQmllint("settings/qmltypes/qmltypes.qml", false, warningsShouldFailArgs(), false)
.contains(QStringLiteral("not a qmldir file. Assuming qmltypes.")));
- QVERIFY(runQmllint("settings/qmlimports/qmlimports.qml", true, QStringList(), false).isEmpty());
+ QVERIFY(runQmllint("settings/qmlimports/qmlimports.qml", true, warningsShouldFailArgs(), false).isEmpty());
}
void TestQmllint::additionalImplicitImport()
@@ -1623,17 +1821,56 @@ void TestQmllint::additionalImplicitImport()
const auto guard = qScopeGuard([this]() {m_linter.clearCache(); });
runTest("additionalImplicitImport.qml", Result::clean(), {}, {},
{ testFile("implicitImportResource.qrc") });
+}
+
+void TestQmllint::qrcUrlImport()
+{
+ const auto guard = qScopeGuard([this]() { m_linter.clearCache(); });
+ QJsonArray warnings;
+ callQmllint(testFile("untitled/main.qml"), true, &warnings, {}, {},
+ { testFile("untitled/qrcUrlImport.qrc") });
+ checkResult(warnings, Result::clean());
}
-void TestQmllint::attachedPropertyReuse()
+void TestQmllint::incorrectImportFromHost_data()
{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<Result>("result");
+
+ QTest::newRow("NonexistentFile")
+ << QStringLiteral("importNonexistentFile.qml")
+ << Result{ { Message{
+ QStringLiteral("File or directory you are trying to import does not exist"),
+ 1, 1 } } };
+#ifndef Q_OS_WIN
+ // there is no /dev/null device on Win
+ QTest::newRow("NullDevice")
+ << QStringLiteral("importNullDevice.qml")
+ << Result{ { Message{ QStringLiteral("is neither a file nor a directory. Are sure the "
+ "import path is correct?"),
+ 1, 1 } } };
+#endif
+}
+
+void TestQmllint::incorrectImportFromHost()
+{
+ QFETCH(QString, filename);
+ QFETCH(Result, result);
+
+ runTest(filename, result);
+}
+void TestQmllint::attachedPropertyReuse()
+{
auto categories = QQmlJSLogger::defaultCategories();
- auto category = std::find(categories.begin(), categories.end(), qmlAttachedPropertyReuse);
+ auto category = std::find_if(categories.begin(), categories.end(), [](const QQmlJS::LoggerCategory& category) {
+ return category.id() == qmlAttachedPropertyReuse;
+ });
Q_ASSERT(category != categories.end());
- category->setLevel(u"warning"_s);
+ category->setLevel(QtWarningMsg);
+ category->setIgnored(false);
runTest("attachedPropNotReused.qml",
Result { { Message { QStringLiteral("Using attached type QQuickKeyNavigationAttached "
"already initialized in a parent "
@@ -1641,6 +1878,24 @@ void TestQmllint::attachedPropertyReuse()
{}, {}, {}, UseDefaultImports, &categories);
runTest("attachedPropEnum.qml", Result::clean(), {}, {}, {}, UseDefaultImports, &categories);
+ runTest("MyStyle/ToolBar.qml", Result {
+ {
+ Message {
+ "Using attached type MyStyle already initialized in a parent scope"_L1,
+ 10,
+ 16
+ }
+ },
+ {},
+ {
+ Message {
+ "Reference it by id instead"_L1,
+ 10,
+ 16
+ }
+ },
+ Result::AutoFixable
+ });
}
void TestQmllint::missingBuiltinsNoCrash()
@@ -1662,13 +1917,13 @@ void TestQmllint::missingBuiltinsNoCrash()
checkResult(warnings,
Result { { Message { QStringLiteral("Failed to find the following builtins: "
- "builtins.qmltypes, jsroot.qmltypes") } } });
+ "jsroot.qmltypes, builtins.qmltypes") } } });
}
void TestQmllint::absolutePath()
{
- QString absPathOutput = runQmllint("memberNotFound.qml", false, {}, true, true, true);
- QString relPathOutput = runQmllint("memberNotFound.qml", false, {}, true, true, false);
+ QString absPathOutput = runQmllint("memberNotFound.qml", false, warningsShouldFailArgs(), true, true, true);
+ QString relPathOutput = runQmllint("memberNotFound.qml", false, warningsShouldFailArgs(), true, true, false);
const QString absolutePath = QFileInfo(testFile("memberNotFound.qml")).absoluteFilePath();
QVERIFY(absPathOutput.contains(absolutePath));
@@ -1683,10 +1938,14 @@ void TestQmllint::importMultipartUri()
void TestQmllint::lintModule_data()
{
QTest::addColumn<QString>("module");
+ QTest::addColumn<QStringList>("importPaths");
+ QTest::addColumn<QStringList>("resources");
QTest::addColumn<Result>("result");
QTest::addRow("Things")
<< u"Things"_s
+ << QStringList()
+ << QStringList()
<< Result {
{ Message {
u"Type \"QPalette\" not found. Used in SomethingEntirelyStrange.palette"_s,
@@ -1696,16 +1955,30 @@ void TestQmllint::lintModule_data()
};
QTest::addRow("missingQmltypes")
<< u"Fake5Compat.GraphicalEffects.private"_s
+ << QStringList()
+ << QStringList()
<< Result { { Message { u"QML types file does not exist"_s } } };
+
+ QTest::addRow("moduleWithQrc")
+ << u"moduleWithQrc"_s
+ << QStringList({ testFile("hidden") })
+ << QStringList({
+ testFile("hidden/qmake_moduleWithQrc.qrc"),
+ testFile("hidden/moduleWithQrc_raw_qml_0.qrc")
+ })
+ << Result::clean();
}
void TestQmllint::lintModule()
{
QFETCH(QString, module);
+ QFETCH(QStringList, importPaths);
+ QFETCH(QStringList, resources);
QFETCH(Result, result);
QJsonArray warnings;
- callQmllint(module, false, &warnings, {}, {}, {}, {}, nullptr, false, LintModule);
+ callQmllint(module, result.flags & Result::ExitsNormally, &warnings, importPaths, {}, resources,
+ UseDefaultImports, nullptr, false, LintModule);
checkResult(warnings, result);
}
@@ -1739,6 +2012,25 @@ void TestQmllint::testLineEndings()
}
}
+void TestQmllint::valueTypesFromString()
+{
+ runTest("valueTypesFromString.qml",
+ Result{ {
+ Message{
+ u"Binding is not supported: Type QSizeF should be constructed using QML_STRUCTURED_VALUE's construction mechanism, instead of a string."_s },
+ Message{
+ u"Binding is not supported: Type QRectF should be constructed using QML_STRUCTURED_VALUE's construction mechanism, instead of a string."_s },
+ Message{
+ u"Binding is not supported: Type QPointF should be constructed using QML_STRUCTURED_VALUE's construction mechanism, instead of a string."_s },
+ },
+ { /*bad messages */ },
+ {
+ Message{ u"({ width: 30, height: 50 })"_s },
+ Message{ u"({ x: 10, y: 20, width: 30, height: 50 })"_s },
+ Message{ u"({ x: 30, y: 50 })"_s },
+ } });
+}
+
#if QT_CONFIG(library)
void TestQmllint::testPlugin()
{
@@ -1780,6 +2072,9 @@ void TestQmllint::testPlugin()
Result { { Message { u"QtQuick.Controls and NO QtQuick present"_s } } });
// Verify that none of the passes do anything when they're not supposed to
runTest("nothing_pluginTest.qml", Result::clean());
+
+ QVERIFY(runQmllint("settings/plugin/elemenpass_pluginSettingTest.qml", true, QStringList(), false)
+ .isEmpty());
}
// TODO: Eventually tests for (real) plugins need to be moved into a separate file
@@ -1835,7 +2130,7 @@ void TestQmllint::quickPlugin()
Message { u"SplitView attached property only works with Items"_s },
Message { u"ScrollIndicator must be attached to a Flickable"_s },
Message { u"ScrollBar must be attached to a Flickable or ScrollView"_s },
- Message { u"Accessible must be attached to an Item"_s },
+ Message { u"Accessible must be attached to an Item or an Action"_s },
Message { u"EnterKey attached property only works with Items"_s },
Message {
u"LayoutDirection attached property only works with Items and Windows"_s },
@@ -1885,8 +2180,108 @@ void TestQmllint::quickPlugin()
runTest("pluginQuick_attachedClean.qml", Result::clean());
runTest("pluginQuick_attachedIgnore.qml", Result::clean());
runTest("pluginQuick_noCrashOnUneresolved.qml", Result {}); // we don't care about the specific warnings
+
+ runTest("pluginQuick_propertyChangesParsed.qml",
+ Result { {
+ Message {
+ u"Property \"myColor\" is custom-parsed in PropertyChanges. "
+ "You should phrase this binding as \"foo.myColor: Qt.rgba(0.5, ...\""_s,
+ 12, 30
+ },
+ Message {
+ u"You should remove any bindings on the \"target\" property and avoid "
+ "custom-parsed bindings in PropertyChanges."_s,
+ 11, 29
+ },
+ Message {
+ u"Unknown property \"notThere\" in PropertyChanges."_s,
+ 13, 31
+ }
+ } });
+ runTest("pluginQuick_propertyChangesInvalidTarget.qml", Result {}); // we don't care about the specific warnings
+}
+
+void TestQmllint::environment_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<bool>("shouldSucceed");
+ QTest::addColumn<QStringList>("extraArgs");
+ QTest::addColumn<Environment>("env");
+ QTest::addColumn<QString>("expectedWarning");
+
+ const QString fileThatNeedsImportPath = testFile(u"NeedImportPath.qml"_s);
+ const QString importPath = testFile(u"ImportPath"_s);
+ const QString invalidImportPath = testFile(u"ImportPathThatDoesNotExist"_s);
+ const QString noWarningExpected;
+
+ QTest::addRow("missing-import-dir")
+ << fileThatNeedsImportPath << false << warningsShouldFailArgs()
+ << Environment{ { u"QML_IMPORT_PATH"_s, importPath } } << noWarningExpected;
+
+ QTest::addRow("import-dir-via-arg")
+ << fileThatNeedsImportPath << true << QStringList{ u"-I"_s, importPath }
+ << Environment{ { u"QML_IMPORT_PATH"_s, invalidImportPath } } << noWarningExpected;
+
+ QTest::addRow("import-dir-via-env")
+ << fileThatNeedsImportPath << true << QStringList{ u"-E"_s }
+ << Environment{ { u"QML_IMPORT_PATH"_s, importPath } }
+ << u"Using import directories passed from environment variable \"QML_IMPORT_PATH\": \"%1\"."_s
+ .arg(importPath);
+
+ QTest::addRow("import-dir-via-env2")
+ << fileThatNeedsImportPath << true << QStringList{ u"-E"_s }
+ << Environment{ { u"QML2_IMPORT_PATH"_s, importPath } }
+ << u"Using import directories passed from the deprecated environment variable \"QML2_IMPORT_PATH\": \"%1\"."_s
+ .arg(importPath);
}
+
+void TestQmllint::environment()
+{
+ QFETCH(QString, file);
+ QFETCH(bool, shouldSucceed);
+ QFETCH(QStringList, extraArgs);
+ QFETCH(Environment, env);
+ QFETCH(QString, expectedWarning);
+
+ const QString output = runQmllint(file, shouldSucceed, extraArgs, false, true, false, env);
+ if (!expectedWarning.isEmpty()) {
+ QVERIFY(output.contains(expectedWarning));
+ }
+}
+
+void TestQmllint::maxWarnings()
+{
+ // warnings are not fatal by default
+ runQmllint(testFile("badScript.qml"), true);
+ // or when max-warnings is set to -1
+ runQmllint(testFile("badScript.qml"), true, {"-W", "-1"});
+ // 1 warning => should fail
+ runQmllint(testFile("badScript.qml"), false, {"--max-warnings", "0"});
+ // only 1 warning => should exit normally
+ runQmllint(testFile("badScript.qml"), true, {"--max-warnings", "1"});
+}
+
#endif
-QTEST_MAIN(TestQmllint)
+void TestQmllint::ignoreSettingsNotCommandLineOptions()
+{
+ const QString importPath = testFile(u"ImportPath"_s);
+ // makes sure that ignore settings only ignores settings and not command line options like
+ // "-I".
+ const QString output = runQmllint(testFile(u"NeedImportPath.qml"_s), true,
+ QStringList{ u"-I"_s, importPath }, true);
+ // should not complain about not finding the module that is in importPath
+ QCOMPARE(output, QString());
+}
+
+void TestQmllint::backslashedQmldirPath()
+{
+ const QString qmldirPath
+ = testFile(u"ImportPath/ModuleInImportPath/qmldir"_s).replace('/', QDir::separator());
+ const QString output = runQmllint(
+ testFile(u"something.qml"_s), true, QStringList{ u"-i"_s, qmldirPath });
+ QVERIFY(output.isEmpty());
+}
+
+QTEST_GUILESS_MAIN(TestQmllint)
#include "tst_qmllint.moc"