aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2011-07-29 10:25:44 +0200
committerQt by Nokia <qt-info@nokia.com>2011-07-29 13:00:52 +0200
commitd410ad364ec0b8877797145c68a4d7c3c98ce1c0 (patch)
tree11862c21e5e465abe3275768918f82cbec2bc6e7 /tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp
parent43b783d09e0899165bbe964a175785ccdfedf6e5 (diff)
Merge the QJSEngine and QJSValue development branch into master.
This replaces the dependency to QtScript with two new builtin classes QJSValue and QJSEngine. This is still work in progress, development continues now in the master branch. Change-Id: I7f5487feb45c972f25a22b10cc81b9218b9805de Reviewed-on: http://codereview.qt.nokia.com/2299 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Simon Hausmann <simon.hausmann@nokia.com>
Diffstat (limited to 'tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp')
-rw-r--r--tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp527
1 files changed, 527 insertions, 0 deletions
diff --git a/tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp b/tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp
new file mode 100644
index 0000000000..1cd5952c54
--- /dev/null
+++ b/tests/auto/declarative/qjsvalueiterator/tst_qjsvalueiterator.cpp
@@ -0,0 +1,527 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <QJSEngine>
+#include <QJSValue>
+#include <QJSValueIterator>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+Q_DECLARE_METATYPE(QJSValue);
+
+class tst_QJSValueIterator : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QJSValueIterator();
+ virtual ~tst_QJSValueIterator();
+
+private slots:
+ void iterateForward_data();
+ void iterateForward();
+ void iterateArray_data();
+ void iterateArray();
+ void iterateString();
+#if 0
+ void iterateGetterSetter();
+#endif
+ void assignObjectToIterator();
+ void iterateNonObject();
+ void iterateOverObjectFromDeletedEngine();
+};
+
+tst_QJSValueIterator::tst_QJSValueIterator()
+{
+}
+
+tst_QJSValueIterator::~tst_QJSValueIterator()
+{
+}
+
+void tst_QJSValueIterator::iterateForward_data()
+{
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QStringList>("propertyValues");
+
+ QTest::newRow("no properties")
+ << QStringList() << QStringList();
+ QTest::newRow("foo=bar")
+ << (QStringList() << "foo")
+ << (QStringList() << "bar");
+ QTest::newRow("foo=bar, baz=123")
+ << (QStringList() << "foo" << "baz")
+ << (QStringList() << "bar" << "123");
+ QTest::newRow("foo=bar, baz=123, rab=oof")
+ << (QStringList() << "foo" << "baz" << "rab")
+ << (QStringList() << "bar" << "123" << "oof");
+}
+
+void tst_QJSValueIterator::iterateForward()
+{
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QStringList, propertyValues);
+ QMap<QString, QString> pmap;
+ QVERIFY(propertyNames.size() == propertyValues.size());
+
+ QJSEngine engine;
+ QJSValue object = engine.newObject();
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QString name = propertyNames.at(i);
+ QString value = propertyValues.at(i);
+ pmap.insert(name, value);
+ object.setProperty(name, QJSValue(&engine, value));
+ }
+ QJSValue otherObject = engine.newObject();
+ otherObject.setProperty("foo", QJSValue(&engine, 123456));
+ otherObject.setProperty("protoProperty", QJSValue(&engine, 654321));
+ object.setPrototype(otherObject); // should not affect iterator
+
+ QStringList lst;
+ QJSValueIterator it(object);
+ while (!pmap.isEmpty()) {
+ QCOMPARE(it.hasNext(), true);
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QString name = it.name();
+ QCOMPARE(pmap.contains(name), true);
+ QCOMPARE(it.name(), name);
+ QCOMPARE(it.value().strictlyEquals(QJSValue(&engine, pmap.value(name))), true);
+ pmap.remove(name);
+ lst.append(name);
+ }
+
+ QCOMPARE(it.hasNext(), false);
+ QCOMPARE(it.hasNext(), false);
+
+ it = object;
+ for (int i = 0; i < lst.count(); ++i) {
+ QCOMPARE(it.hasNext(), true);
+ it.next();
+ QCOMPARE(it.name(), lst.at(i));
+ }
+}
+
+void tst_QJSValueIterator::iterateArray_data()
+{
+ QTest::addColumn<QStringList>("propertyNames");
+ QTest::addColumn<QStringList>("propertyValues");
+
+ QTest::newRow("no elements") << QStringList() << QStringList();
+
+ QTest::newRow("0=foo, 1=barr")
+ << (QStringList() << "0" << "1")
+ << (QStringList() << "foo" << "bar");
+
+
+ QTest::newRow("0=foo, 3=barr")
+ << (QStringList() << "0" << "1" << "2" << "3")
+ << (QStringList() << "foo" << "" << "" << "bar");
+}
+
+void tst_QJSValueIterator::iterateArray()
+{
+ QFETCH(QStringList, propertyNames);
+ QFETCH(QStringList, propertyValues);
+
+ QJSEngine engine;
+ QJSValue array = engine.newArray();
+
+ // Fill the array
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ array.setProperty(propertyNames.at(i), propertyValues.at(i));
+ }
+
+ // Iterate thru array properties. Note that the QJSValueIterator doesn't guarantee
+ // any order on the iteration!
+ int length = array.property("length").toInt32();
+ QCOMPARE(length, propertyNames.size());
+
+ bool iteratedThruLength = false;
+ QHash<QString, QJSValue> arrayProperties;
+ QJSValueIterator it(array);
+
+ // Iterate forward
+ while (it.hasNext()) {
+ it.next();
+
+ const QString name = it.name();
+ if (name == QString::fromLatin1("length")) {
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
+ iteratedThruLength = true;
+ continue;
+ }
+
+ // Storing the properties we iterate in a hash to compare with test data.
+ QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
+ arrayProperties.insert(name, it.value());
+ QVERIFY(it.value().strictlyEquals(array.property(name)));
+ }
+
+ // Verify properties
+ QVERIFY(iteratedThruLength);
+ QCOMPARE(arrayProperties.size(), propertyNames.size());
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QVERIFY(arrayProperties.contains(propertyNames.at(i)));
+ QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
+ }
+
+#if 0
+
+ // Iterate backwards
+ arrayProperties.clear();
+ iteratedThruLength = false;
+ it.toBack();
+
+ while (it.hasPrevious()) {
+ it.previous();
+
+ const QString name = it.name();
+ if (name == QString::fromLatin1("length")) {
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
+ QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
+ iteratedThruLength = true;
+ continue;
+ }
+
+ // Storing the properties we iterate in a hash to compare with test data.
+ QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
+ arrayProperties.insert(name, it.value());
+ QCOMPARE(it.flags(), array.propertyFlags(name));
+ QVERIFY(it.value().strictlyEquals(array.property(name)));
+ }
+
+ // Verify properties
+ QVERIFY(iteratedThruLength);
+ QCOMPARE(arrayProperties.size(), propertyNames.size());
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QVERIFY(arrayProperties.contains(propertyNames.at(i)));
+ QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
+ }
+
+ // ### Do we still need this test?
+ // Forward test again but as object
+ arrayProperties.clear();
+ iteratedThruLength = false;
+ QJSValue arrayObject = engine.toObject(array);
+ QJSValueIterator it2(arrayObject);
+
+ while (it2.hasNext()) {
+ it2.next();
+
+ const QString name = it2.name();
+ if (name == QString::fromLatin1("length")) {
+ QVERIFY(it2.value().isNumber());
+ QCOMPARE(it2.value().toInt32(), length);
+ QCOMPARE(it2.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
+ QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
+ iteratedThruLength = true;
+ continue;
+ }
+
+ // Storing the properties we iterate in a hash to compare with test data.
+ QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
+ arrayProperties.insert(name, it2.value());
+ QCOMPARE(it2.flags(), arrayObject.propertyFlags(name));
+ QVERIFY(it2.value().strictlyEquals(arrayObject.property(name)));
+ }
+
+ // Verify properties
+ QVERIFY(iteratedThruLength);
+ QCOMPARE(arrayProperties.size(), propertyNames.size());
+ for (int i = 0; i < propertyNames.size(); ++i) {
+ QVERIFY(arrayProperties.contains(propertyNames.at(i)));
+ QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
+ }
+#endif
+}
+
+void tst_QJSValueIterator::iterateString()
+{
+ QJSEngine engine;
+ QJSValue str = QJSValue(&engine, QString::fromLatin1("ciao"));
+ QVERIFY(str.isString());
+ QJSValue obj = str.toObject();
+ QVERIFY(obj.property("length").isNumber());
+ int length = obj.property("length").toInt32();
+ QCOMPARE(length, 4);
+
+ QJSValueIterator it(obj);
+ QHash<QString, QJSValue> stringProperties;
+ bool iteratedThruLength = false;
+
+ while (it.hasNext()) {
+ it.next();
+ const QString name = it.name();
+
+ if (name == QString::fromLatin1("length")) {
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
+ iteratedThruLength = true;
+ continue;
+ }
+
+ QVERIFY2(!stringProperties.contains(name), "property appeared more than once during iteration.");
+ stringProperties.insert(name, it.value());
+ QVERIFY(it.value().strictlyEquals(obj.property(name)));
+ }
+
+ QVERIFY(iteratedThruLength);
+ QCOMPARE(stringProperties.size(), length);
+#if 0
+ // And going backwards
+ iteratedThruLength = false;
+ stringProperties.clear();
+ it.toBack();
+
+ while (it.hasPrevious()) {
+ it.previous();
+ const QString name = it.name();
+
+ if (name == QString::fromLatin1("length")) {
+ QVERIFY(it.value().isNumber());
+ QCOMPARE(it.value().toInt32(), length);
+ QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
+ iteratedThruLength = true;
+ continue;
+ }
+
+ QVERIFY2(!stringProperties.contains(name), "property appeared more than once during iteration.");
+ stringProperties.insert(name, it.value());
+ QVERIFY(it.value().strictlyEquals(obj.property(name)));
+ }
+#endif
+}
+
+#if 0 // FIXME what we should to keep from here?
+static QJSValue myGetterSetter(QScriptContext *ctx, QJSEngine *)
+{
+ if (ctx->argumentCount() == 1)
+ ctx->thisObject().setProperty("bar", ctx->argument(0));
+ return ctx->thisObject().property("bar");
+}
+
+static QJSValue myGetter(QScriptContext *ctx, QJSEngine *)
+{
+ return ctx->thisObject().property("bar");
+}
+
+static QJSValue mySetter(QScriptContext *ctx, QJSEngine *)
+{
+ ctx->thisObject().setProperty("bar", ctx->argument(0));
+ return ctx->argument(0);
+}
+
+void tst_QJSValueIterator::iterateGetterSetter()
+{
+ // unified getter/setter function
+ {
+ QJSEngine eng;
+ QJSValue obj = eng.newObject();
+ obj.setProperty("foo", eng.newFunction(myGetterSetter),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ QJSValue val(&eng, 123);
+ obj.setProperty("foo", val);
+ QVERIFY(obj.property("bar").strictlyEquals(val));
+ QVERIFY(obj.property("foo").strictlyEquals(val));
+
+ QJSValueIterator it(obj);
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::PropertyGetter | QScriptValue::PropertySetter));
+ QVERIFY(it.value().strictlyEquals(val));
+ QJSValue val2(&eng, 456);
+ it.setValue(val2);
+ QVERIFY(obj.property("bar").strictlyEquals(val2));
+ QVERIFY(obj.property("foo").strictlyEquals(val2));
+
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+ QVERIFY(!it.hasNext());
+
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::PropertyGetter | QScriptValue::PropertySetter));
+ QVERIFY(it.value().strictlyEquals(val2));
+ it.setValue(val);
+ QVERIFY(obj.property("bar").strictlyEquals(val));
+ QVERIFY(obj.property("foo").strictlyEquals(val));
+ }
+ // separate getter/setter function
+ for (int x = 0; x < 2; ++x) {
+ QJSEngine eng;
+ QJSValue obj = eng.newObject();
+ if (x == 0) {
+ obj.setProperty("foo", eng.newFunction(myGetter), QScriptValue::PropertyGetter);
+ obj.setProperty("foo", eng.newFunction(mySetter), QScriptValue::PropertySetter);
+ } else {
+ obj.setProperty("foo", eng.newFunction(mySetter), QScriptValue::PropertySetter);
+ obj.setProperty("foo", eng.newFunction(myGetter), QScriptValue::PropertyGetter);
+ }
+ QJSValue val(&eng, 123);
+ obj.setProperty("foo", val);
+ QVERIFY(obj.property("bar").strictlyEquals(val));
+ QVERIFY(obj.property("foo").strictlyEquals(val));
+
+ QJSValueIterator it(obj);
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QVERIFY(it.value().strictlyEquals(val));
+ QJSValue val2(&eng, 456);
+ it.setValue(val2);
+ QVERIFY(obj.property("bar").strictlyEquals(val2));
+ QVERIFY(obj.property("foo").strictlyEquals(val2));
+
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+ QVERIFY(!it.hasNext());
+
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+ QVERIFY(it.hasPrevious());
+ it.previous();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+ QVERIFY(it.value().strictlyEquals(val2));
+ it.setValue(val);
+ QVERIFY(obj.property("bar").strictlyEquals(val));
+ QVERIFY(obj.property("foo").strictlyEquals(val));
+ }
+}
+#endif
+
+void tst_QJSValueIterator::assignObjectToIterator()
+{
+ QJSEngine eng;
+ QJSValue obj1 = eng.newObject();
+ obj1.setProperty("foo", 123);
+ QJSValue obj2 = eng.newObject();
+ obj2.setProperty("bar", 456);
+
+ QJSValueIterator it(obj1);
+ QVERIFY(it.hasNext());
+ it.next();
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+
+ it = obj1;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("foo"));
+
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+
+ it = obj2;
+ QVERIFY(it.hasNext());
+ it.next();
+ QCOMPARE(it.name(), QString::fromLatin1("bar"));
+}
+
+void tst_QJSValueIterator::iterateNonObject()
+{
+ QJSValueIterator it(123);
+ QVERIFY(!it.hasNext());
+ it.next();
+ it.name();
+ it.value();
+ QJSValue num(5);
+ it = num;
+ QVERIFY(!it.hasNext());
+}
+
+void tst_QJSValueIterator::iterateOverObjectFromDeletedEngine()
+{
+ QJSEngine *engine = new QJSEngine;
+ QJSValue objet = engine->newObject();
+
+ // populate object with properties
+ QHash<QString, int> properties;
+ properties.insert("foo",1235);
+ properties.insert("oof",5321);
+ properties.insert("ofo",3521);
+ QHash<QString, int>::const_iterator i = properties.constBegin();
+ for (; i != properties.constEnd(); ++i) {
+ objet.setProperty(i.key(), i.value());
+ }
+
+ // start iterating
+ QJSValueIterator it(objet);
+ it.next();
+ QVERIFY(properties.contains(it.name()));
+
+ delete engine;
+
+ QVERIFY(!objet.isValid());
+ QVERIFY(it.name().isEmpty());
+ QVERIFY(!it.value().isValid());
+
+ QVERIFY(!it.hasNext());
+ it.next();
+
+ QVERIFY(it.name().isEmpty());
+ QVERIFY(!it.value().isValid());
+
+}
+
+QTEST_MAIN(tst_QJSValueIterator)
+#include "tst_qjsvalueiterator.moc"