summaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/declarative/qmlparser/tst_qmlparser.cpp')
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp309
1 files changed, 75 insertions, 234 deletions
diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
index efd45d3..f17583a 100644
--- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
+++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
@@ -1,6 +1,8 @@
#include <qtest.h>
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlcomponent.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qdebug.h>
class MyInterface
{
@@ -43,7 +45,7 @@ public:
MyInterface *interface() const { return m_interface; }
void setInterface(MyInterface *iface) { m_interface = iface; }
- Q_CLASSINFO("defaultMethod", "basicSlot()");
+ Q_CLASSINFO("DefaultMethod", "basicSlot()");
public slots:
void basicSlot() { qWarning("MyQmlObject::basicSlot"); }
@@ -133,27 +135,16 @@ public:
tst_qmlparser() {}
private slots:
+
+ void errors_data();
+ void errors();
+
void simpleObject();
void simpleContainer();
- void unregisteredObject();
- void nonexistantProperty();
- void unsupportedProperty();
- //void setProperties();
- void wrongType();
- void readOnly();
- //void dotProperties();
- void nullDotProperty();
- void fakeDotProperty();
- //void readWriteDotProperty();
- void emptyInput();
- void missingObject();
- //void invalidXML();
- void duplicateIDs();
- void invalidID();
void interfaceProperty();
void interfaceQmlList();
void interfaceQList();
- //void cannotAssignBindingToSignal();
+
void assignObjectToSignal();
// regression tests for crashes
@@ -163,242 +154,101 @@ private:
QmlEngine engine;
};
-void tst_qmlparser::simpleObject()
-{
- QmlComponent component(&engine, "MyQmlObject {}");
- QObject *object = component.create();
- QVERIFY(object != 0);
-}
+#define VERIFY_ERRORS(errorfile) \
+ if (!errorfile) { \
+ QVERIFY(!component.isError()); \
+ QVERIFY(component.errors().isEmpty()); \
+ } else { \
+ QFile file(errorfile); \
+ QVERIFY(file.open(QIODevice::ReadOnly)); \
+ QByteArray data = file.readAll(); \
+ QList<QByteArray> expected = data.split('\n'); \
+ expected.removeAll(QByteArray("")); \
+ QList<QmlError> errors = component.errors(); \
+ QList<QByteArray> actual; \
+ for (int ii = 0; ii < errors.count(); ++ii) { \
+ const QmlError &error = errors.at(ii); \
+ QByteArray errorStr = QByteArray::number(error.line()) + ":" + \
+ QByteArray::number(error.column()) + ":" + \
+ error.description().toUtf8(); \
+ actual << errorStr; \
+ } \
+ if (qgetenv("DEBUG") != "") \
+ qWarning() << expected << actual; \
+ QCOMPARE(expected, actual); \
+ }
-void tst_qmlparser::simpleContainer()
-{
- QmlComponent component(&engine, "MyContainer {\nMyQmlObject{}\nMyQmlObject{}\n}");
- MyContainer *container= qobject_cast<MyContainer*>(component.create());
- QVERIFY(container != 0);
- QCOMPARE(container->children()->count(),2);
-}
+#define TEST_FILE(filename) \
+ QUrl::fromLocalFile(QApplication::applicationDirPath() + "/" + filename)
-void tst_qmlparser::unregisteredObject()
+void tst_qmlparser::errors_data()
{
- QmlComponent component(&engine, "UnRegisteredObject {}", QUrl("myprogram.qml"));
- QTest::ignoreMessage(QtWarningMsg, "Unable to create object of type 'UnRegisteredObject' @myprogram.qml:1");
- QObject *object = component.create();
- QVERIFY(object == 0);
-}
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("errorFile");
+ QTest::addColumn<bool>("create");
-void tst_qmlparser::nonexistantProperty()
-{
- //NOTE: these first 3 should all have the same error message
- {
- QmlComponent component(&engine, "MyQmlObject { something: 24 }");
- QTest::ignoreMessage(QtWarningMsg, "Unknown property 'something' @<unspecified file>:1");
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
+ QTest::newRow("nonExistantProperty.1") << "nonexistantProperty.1.txt" << "nonexistantProperty.1.errors.txt" << true;
+ QTest::newRow("nonExistantProperty.2") << "nonexistantProperty.2.txt" << "nonexistantProperty.2.errors.txt" << true;
+ QTest::newRow("nonExistantProperty.3") << "nonexistantProperty.3.txt" << "nonexistantProperty.3.errors.txt" << true;
+ QTest::newRow("nonExistantProperty.4") << "nonexistantProperty.4.txt" << "nonexistantProperty.4.errors.txt" << true;
+ QTest::newRow("nonExistantProperty.5") << "nonexistantProperty.5.txt" << "nonexistantProperty.5.errors.txt" << false;
+ QTest::newRow("nonExistantProperty.6") << "nonexistantProperty.6.txt" << "nonexistantProperty.6.errors.txt" << true;
- {
- QmlComponent component(&engine, "MyQmlObject {\n something: 24\n}");
- QTest::ignoreMessage(QtWarningMsg, "Unknown property 'something' @<unspecified file>:2");
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
- //non-existant using binding
- {
- QmlComponent component(&engine, "MyQmlObject { something: 1 + 1 }");
- QTest::ignoreMessage(QtWarningMsg, "Unknown property 'something' @<unspecified file>:1");
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
+ QTest::newRow("wrongType (string for int)") << "wrongType.1.txt" << "wrongType.1.errors.txt" << false;
+ QTest::newRow("wrongType (int for bool)") << "wrongType.2.txt" << "wrongType.2.errors.txt" << false;
+ QTest::newRow("wrongType (bad rect)") << "wrongType.3.txt" << "wrongType.3.errors.txt" << false;
- {
- QmlComponent component(&engine, "MyQmlObject { something: }");
- QObject *object = component.create();
- QVERIFY(object != 0);
- }
- //non-existant value-type default property
- {
- QmlComponent component(&engine, "MyQmlObject {\n24\n}");
- QTest::ignoreMessage(QtWarningMsg, "Unable to resolve default property @<unspecified file>:3");
- // XXX would 2 be a better line number in this case? Message should also be improved.
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
+ QTest::newRow("nonExistantProperty.1") << "readOnly.1.txt" << "readOnly.1.errors.txt" << false;
+ QTest::newRow("nonExistantProperty.2") << "readOnly.2.txt" << "readOnly.2.errors.txt" << true;
- //non-existant object-type default property
- {
- QmlComponent component(&engine, "MyQmlObject {\nMyQmlObject{}\n}");
- QTest::ignoreMessage(QtWarningMsg, "Unable to assign to non-existant property @<unspecified file>:2");
- // XXX Message needs to be improved (and should be closer to value-type message).
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
-}
-void tst_qmlparser::unsupportedProperty()
-{
- QTest::ignoreMessage(QtWarningMsg, "Property 'matrix' is of an unknown type @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { matrix: \"1,0,0,0,1,0,0,0,1\" }");
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
- QVERIFY(object == 0);
+ QTest::newRow("unsupportedProperty") << "unsupportedProperty.txt" << "unsupportedProperty.errors.txt" << true;
+ QTest::newRow("nullDotProperty") << "nullDotProperty.txt" << "nullDotProperty.errors.txt" << true;
+ QTest::newRow("fakeDotProperty") << "fakeDotProperty.txt" << "fakeDotProperty.errors.txt" << true;
+ QTest::newRow("duplicateIDs") << "duplicateIDs.txt" << "duplicateIDs.errors.txt" << false;
+ QTest::newRow("invalidID") << "invalidID.txt" << "invalidID.errors.txt" << false;
+ QTest::newRow("unregisteredObject") << "unregisteredObject.txt" << "unregisteredObject.errors.txt" << false;
+ QTest::newRow("empty") << "empty.txt" << "empty.errors.txt" << false;
+ QTest::newRow("missingObject") << "missingObject.txt" << "missingObject.errors.txt" << false;
}
-void tst_qmlparser::wrongType()
+void tst_qmlparser::errors()
{
- //string for int
- {
- QTest::ignoreMessage(QtWarningMsg, "Can't assign value 'hello' to property 'value' @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { value: \"hello\" }");
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
- QVERIFY(object == 0);
- }
-
- //int for bool
- {
- QTest::ignoreMessage(QtWarningMsg, "Can't assign value '5' to property 'enabled' @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { enabled: 5 }");
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
- QVERIFY(object == 0);
- }
+ QFETCH(QString, file);
+ QFETCH(QString, errorFile);
+ QFETCH(bool, create);
- //bad format for rect
- {
- QTest::ignoreMessage(QtWarningMsg, "Can't assign value '5,5x10' to property 'rect' @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { rect: \"5,5x10\" }");
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
- QVERIFY(object == 0);
- }
-
- //TODO: more types (including float-to-int, complex types, etc)
-}
-
-void tst_qmlparser::readOnly()
-{
- {
- QTest::ignoreMessage(QtWarningMsg, "Can't assign value 'hello' to property 'readOnlyString' because 'readOnlyString' is read-only @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { readOnlyString: \"hello\" }");
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
+ QmlComponent component(&engine, TEST_FILE(file));
- {
- QTest::ignoreMessage(QtWarningMsg, "Can't assign a binding to property 'readOnlyString' because 'readOnlyString' is read-only @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { readOnlyString: {'hello'} }");
+ if(create) {
QObject *object = component.create();
QVERIFY(object == 0);
}
-}
-void tst_qmlparser::nullDotProperty()
-{
- QTest::ignoreMessage(QtWarningMsg, "Can't set properties on 'obj' because it is null @<unspecified file>:1");
- QmlComponent component(&engine, "MyDotPropertyObject { obj.value: 1 }");
- QObject *object = component.create();
- QVERIFY(object == 0);
+ VERIFY_ERRORS(errorFile.toLatin1().constData());
}
-void tst_qmlparser::fakeDotProperty()
+void tst_qmlparser::simpleObject()
{
- QTest::ignoreMessage(QtWarningMsg, "Can't set properties on 'value' because it isn't a known object type @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { value.something: \"hello\" }");
+ QmlComponent component(&engine, TEST_FILE("simpleObject.txt"));
+ VERIFY_ERRORS(0);
QObject *object = component.create();
- QVERIFY(object == 0);
-}
-
-//XXX need to define correct behavior first
-/*void tst_qmlparser::readWriteDotProperty()
-{
- QmlComponent component(&engine, "MyDotPropertyObject { readWriteObj.value: 1 }");
- MyDotPropertyObject *object = qobject_cast<MyDotPropertyObject*>(component.create());
QVERIFY(object != 0);
- QCOMPARE(object->readWriteObj()->value(),1);
-
- {
- QmlComponent component(&engine, "MyContainer { MyQmlObject { id: Obj value: 1 } MyDotPropertyObject { readWriteObj: Obj } }");
- MyContainer *object = qobject_cast<MyContainer*>(component.create());
- QVERIFY(object != 0);
- MyDotPropertyObject *dpo = qobject_cast<MyDotPropertyObject *>(object->children()->at(1));
- QCOMPARE(dpo->readWriteObj()->value(),1);
- }
-}*/
-
-void tst_qmlparser::emptyInput()
-{
- QTest::ignoreMessage(QtCriticalMsg, "No Qml was specified for parsing.");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @<unspecified file>:-1");
- QmlComponent component(&engine, "");
- QObject *object = component.create();
- QVERIFY(object == 0);
-}
-
-void tst_qmlparser::missingObject()
-{
- QTest::ignoreMessage(QtCriticalMsg, "Can't have a property with no object @<unspecified file>:1");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @<unspecified file>:-1");
- QmlComponent component(&engine, "something:");
- QObject *object = component.create();
- QVERIFY(object == 0);
-}
-
-
-/*void tst_qmlparser::invalidXML()
-{
- //extra stuff on end
- {
- QTest::ignoreMessage(QtCriticalMsg, "Extra content at end of document. @myprogram.qml:1");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @myprogram.qml:-1");
- QmlComponent component(&engine, "<MyQmlObject/><something/>", QUrl("myprogram.qml"));
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
-
- //mismatched tags
- {
- QTest::ignoreMessage(QtCriticalMsg, "Opening and ending tag mismatch. @myprogram.qml:2");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @myprogram.qml:-1");
- QmlComponent component(&engine, "<MyQmlObject>\n</MyContainer>", QUrl("myprogram.qml"));
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
-
- {
- QTest::ignoreMessage(QtCriticalMsg, "Expected '>' or '/', but got '<'. @myprogram.qml:1");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @myprogram.qml:-1");
- QmlComponent component(&engine, "<MyQmlObject < />", QUrl("myprogram.qml"));
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
-
- {
- QTest::ignoreMessage(QtCriticalMsg, "Premature end of document. @myprogram.qml:1");
- QTest::ignoreMessage(QtWarningMsg, "Can't compile because of earlier errors @myprogram.qml:-1");
- QmlComponent component(&engine, "<MyQmlObject something=\" />", QUrl("myprogram.qml"));
- QObject *object = component.create();
- QVERIFY(object == 0);
- }
-
-}*/
-
-void tst_qmlparser::duplicateIDs()
-{
- QTest::ignoreMessage(QtWarningMsg, "An id (\"MyID\") is not unique within its scope. @<unspecified file>:3");
- QmlComponent component(&engine, "MyContainer {\nMyQmlObject { id: MyID }\nMyQmlObject { id: MyID }\n}");
- QObject *object = component.create();
- QVERIFY(object == 0);
}
-void tst_qmlparser::invalidID()
+void tst_qmlparser::simpleContainer()
{
- QTest::ignoreMessage(QtWarningMsg, "'1' is not a valid id @<unspecified file>:1");
- QmlComponent component(&engine, "MyQmlObject { id: 1 }");
- QObject *object = component.create();
- QVERIFY(object == 0);
+ QmlComponent component(&engine, TEST_FILE("simpleContainer.txt"));
+ MyContainer *container= qobject_cast<MyContainer*>(component.create());
+ QVERIFY(container != 0);
+ QCOMPARE(container->children()->count(),2);
}
void tst_qmlparser::interfaceProperty()
{
- QmlComponent component(&engine, "MyQmlObject { interface: MyQmlObject }");
+ QmlComponent component(&engine, TEST_FILE("interfaceProperty.txt"));
MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
QVERIFY(object != 0);
QVERIFY(object->interface());
@@ -407,7 +257,7 @@ void tst_qmlparser::interfaceProperty()
void tst_qmlparser::interfaceQmlList()
{
- QmlComponent component(&engine, "MyContainer { qmllistInterfaces: MyQmlObject {} }");
+ QmlComponent component(&engine, TEST_FILE("interfaceQmlList.txt"));
MyContainer *container= qobject_cast<MyContainer*>(component.create());
QVERIFY(container != 0);
QVERIFY(container->qmllistAccessor().count() == 2);
@@ -417,7 +267,7 @@ void tst_qmlparser::interfaceQmlList()
void tst_qmlparser::interfaceQList()
{
- QmlComponent component(&engine, "MyContainer { qlistInterfaces: MyQmlObject {} }");
+ QmlComponent component(&engine, TEST_FILE("interfaceQList.txt"));
MyContainer *container= qobject_cast<MyContainer*>(component.create());
QVERIFY(container != 0);
QVERIFY(container->qlistInterfaces()->count() == 2);
@@ -425,17 +275,9 @@ void tst_qmlparser::interfaceQList()
QVERIFY(container->qlistInterfaces()->at(ii)->id == 913);
}
-/*void tst_qmlparser::cannotAssignBindingToSignal()
-{
- QTest::ignoreMessage(QtWarningMsg, "Cannot assign binding to signal property @<unspecified file>:1");
- QmlComponent component(&engine, "<MyQmlObject onBasicSignal=\"{print(1921)}\" />");
- MyContainer *container= qobject_cast<MyContainer*>(component.create());
- QVERIFY(container == 0);
-}*/
-
void tst_qmlparser::assignObjectToSignal()
{
- QmlComponent component(&engine, "MyQmlObject { onBasicSignal: MyQmlObject {} }");
+ QmlComponent component(&engine, TEST_FILE("assignObjectToSignal.txt"));
MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
QVERIFY(object != 0);
QTest::ignoreMessage(QtWarningMsg, "MyQmlObject::basicSlot");
@@ -445,7 +287,6 @@ void tst_qmlparser::assignObjectToSignal()
void tst_qmlparser::crash1()
{
QmlComponent component(&engine, "Component {}");
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
}
QTEST_MAIN(tst_qmlparser)