| /**************************************************************************** |
| ** |
| ** Copyright (C) 2018 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the test suite of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| |
| #include <QtTest/QtTest> |
| |
| #include <QtScript/qscriptengine.h> |
| #include <QtScript/qscriptvalueiterator.h> |
| |
| Q_DECLARE_METATYPE(QScriptValue); |
| |
| class tst_QScriptValueIterator : public QObject |
| { |
| Q_OBJECT |
| |
| public: |
| tst_QScriptValueIterator(); |
| virtual ~tst_QScriptValueIterator(); |
| |
| private slots: |
| void iterateForward_data(); |
| void iterateForward(); |
| void iterateBackward_data(); |
| void iterateBackward(); |
| void iterateArray_data(); |
| void iterateArray(); |
| void iterateBackAndForth(); |
| void setValue(); |
| void remove(); |
| void iterateString(); |
| void iterateGetterSetter(); |
| void assignObjectToIterator(); |
| void iterateNonObject(); |
| void iterateOverObjectFromDeletedEngine(); |
| }; |
| |
| tst_QScriptValueIterator::tst_QScriptValueIterator() |
| { |
| } |
| |
| tst_QScriptValueIterator::~tst_QScriptValueIterator() |
| { |
| } |
| |
| void tst_QScriptValueIterator::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_QScriptValueIterator::iterateForward() |
| { |
| QFETCH(QStringList, propertyNames); |
| QFETCH(QStringList, propertyValues); |
| QMap<QString, QString> pmap; |
| QVERIFY(propertyNames.size() == propertyValues.size()); |
| |
| QScriptEngine engine; |
| QScriptValue 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, QScriptValue(&engine, value)); |
| } |
| QScriptValue otherObject = engine.newObject(); |
| otherObject.setProperty("foo", QScriptValue(&engine, 123456)); |
| otherObject.setProperty("protoProperty", QScriptValue(&engine, 654321)); |
| object.setPrototype(otherObject); // should not affect iterator |
| |
| QStringList lst; |
| QScriptValueIterator 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.flags(), object.propertyFlags(name)); |
| QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true); |
| QCOMPARE(it.scriptName(), engine.toStringHandle(name)); |
| pmap.remove(name); |
| lst.append(name); |
| } |
| |
| QCOMPARE(it.hasNext(), false); |
| QCOMPARE(it.hasNext(), false); |
| |
| it.toFront(); |
| for (int i = 0; i < lst.count(); ++i) { |
| QCOMPARE(it.hasNext(), true); |
| it.next(); |
| QCOMPARE(it.name(), lst.at(i)); |
| } |
| |
| for (int i = 0; i < lst.count(); ++i) { |
| QCOMPARE(it.hasPrevious(), true); |
| it.previous(); |
| QCOMPARE(it.name(), lst.at(lst.count()-1-i)); |
| } |
| QCOMPARE(it.hasPrevious(), false); |
| } |
| |
| void tst_QScriptValueIterator::iterateBackward_data() |
| { |
| iterateForward_data(); |
| } |
| |
| void tst_QScriptValueIterator::iterateBackward() |
| { |
| QFETCH(QStringList, propertyNames); |
| QFETCH(QStringList, propertyValues); |
| QMap<QString, QString> pmap; |
| QVERIFY(propertyNames.size() == propertyValues.size()); |
| |
| QScriptEngine engine; |
| QScriptValue 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, QScriptValue(&engine, value)); |
| } |
| |
| QStringList lst; |
| QScriptValueIterator it(object); |
| it.toBack(); |
| while (!pmap.isEmpty()) { |
| QCOMPARE(it.hasPrevious(), true); |
| QCOMPARE(it.hasPrevious(), true); |
| it.previous(); |
| QString name = it.name(); |
| QCOMPARE(pmap.contains(name), true); |
| QCOMPARE(it.name(), name); |
| QCOMPARE(it.flags(), object.propertyFlags(name)); |
| QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true); |
| pmap.remove(name); |
| lst.append(name); |
| } |
| |
| QCOMPARE(it.hasPrevious(), false); |
| QCOMPARE(it.hasPrevious(), false); |
| |
| it.toBack(); |
| for (int i = 0; i < lst.count(); ++i) { |
| QCOMPARE(it.hasPrevious(), true); |
| it.previous(); |
| QCOMPARE(it.name(), lst.at(i)); |
| } |
| |
| for (int i = 0; i < lst.count(); ++i) { |
| QCOMPARE(it.hasNext(), true); |
| it.next(); |
| QCOMPARE(it.name(), lst.at(lst.count()-1-i)); |
| } |
| QCOMPARE(it.hasNext(), false); |
| } |
| |
| void tst_QScriptValueIterator::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_QScriptValueIterator::iterateArray() |
| { |
| QFETCH(QStringList, propertyNames); |
| QFETCH(QStringList, propertyValues); |
| |
| QScriptEngine engine; |
| QScriptValue 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 QScriptValueIterator doesn't guarantee |
| // any order on the iteration! |
| int length = array.property("length").toInt32(); |
| QCOMPARE(length, propertyNames.size()); |
| |
| bool iteratedThruLength = false; |
| QHash<QString, QScriptValue> arrayProperties; |
| QScriptValueIterator 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); |
| 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)); |
| } |
| |
| // 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; |
| QScriptValue arrayObject = engine.toObject(array); |
| QScriptValueIterator 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)); |
| } |
| } |
| |
| void tst_QScriptValueIterator::iterateBackAndForth() |
| { |
| QScriptEngine engine; |
| { |
| QScriptValue object = engine.newObject(); |
| object.setProperty("foo", QScriptValue(&engine, "bar")); |
| object.setProperty("rab", QScriptValue(&engine, "oof"), |
| QScriptValue::SkipInEnumeration); // should not affect iterator |
| QScriptValueIterator it(object); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| QVERIFY(it.hasPrevious()); |
| it.previous(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| QVERIFY(it.hasPrevious()); |
| it.previous(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("rab")); |
| QVERIFY(it.hasPrevious()); |
| it.previous(); |
| QCOMPARE(it.name(), QLatin1String("rab")); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("rab")); |
| QVERIFY(it.hasPrevious()); |
| it.previous(); |
| QCOMPARE(it.name(), QLatin1String("rab")); |
| } |
| { |
| // hasNext() and hasPrevious() cache their result; verify that the result is in sync |
| QScriptValue object = engine.newObject(); |
| object.setProperty("foo", QScriptValue(&engine, "bar")); |
| object.setProperty("rab", QScriptValue(&engine, "oof")); |
| QScriptValueIterator it(object); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QString::fromLatin1("foo")); |
| QVERIFY(it.hasNext()); |
| it.previous(); |
| QCOMPARE(it.name(), QString::fromLatin1("foo")); |
| QVERIFY(!it.hasPrevious()); |
| it.next(); |
| QCOMPARE(it.name(), QString::fromLatin1("foo")); |
| QVERIFY(it.hasPrevious()); |
| it.next(); |
| QCOMPARE(it.name(), QString::fromLatin1("rab")); |
| } |
| } |
| |
| void tst_QScriptValueIterator::setValue() |
| { |
| QScriptEngine engine; |
| QScriptValue object = engine.newObject(); |
| object.setProperty("foo", QScriptValue(&engine, "bar")); |
| QScriptValueIterator it(object); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| it.setValue(QScriptValue(&engine, "baz")); |
| QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("baz"))), true); |
| QCOMPARE(object.property("foo").toString(), QLatin1String("baz")); |
| it.setValue(QScriptValue(&engine, "zab")); |
| QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("zab"))), true); |
| QCOMPARE(object.property("foo").toString(), QLatin1String("zab")); |
| } |
| |
| void tst_QScriptValueIterator::remove() |
| { |
| QScriptEngine engine; |
| QScriptValue object = engine.newObject(); |
| object.setProperty("foo", QScriptValue(&engine, "bar"), |
| QScriptValue::SkipInEnumeration); // should not affect iterator |
| object.setProperty("rab", QScriptValue(&engine, "oof")); |
| QScriptValueIterator it(object); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("foo")); |
| it.remove(); |
| QCOMPARE(it.hasPrevious(), false); |
| QCOMPARE(object.property("foo").isValid(), false); |
| QCOMPARE(object.property("rab").toString(), QLatin1String("oof")); |
| it.next(); |
| QCOMPARE(it.name(), QLatin1String("rab")); |
| QCOMPARE(it.value().toString(), QLatin1String("oof")); |
| QCOMPARE(it.hasNext(), false); |
| it.remove(); |
| QCOMPARE(object.property("rab").isValid(), false); |
| QCOMPARE(it.hasPrevious(), false); |
| QCOMPARE(it.hasNext(), false); |
| } |
| |
| void tst_QScriptValueIterator::iterateString() |
| { |
| QScriptEngine engine; |
| QScriptValue str = QScriptValue(&engine, QString::fromLatin1("ciao")); |
| QVERIFY(str.isString()); |
| QScriptValue obj = str.toObject(); |
| QVERIFY(obj.property("length").isNumber()); |
| int length = obj.property("length").toInt32(); |
| QCOMPARE(length, 4); |
| |
| QScriptValueIterator it(obj); |
| QHash<QString, QScriptValue> 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); |
| QCOMPARE(it.flags(), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); |
| 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()); |
| QCOMPARE(it.flags(), obj.propertyFlags(name)); |
| QVERIFY(it.value().strictlyEquals(obj.property(name))); |
| } |
| |
| QVERIFY(iteratedThruLength); |
| QCOMPARE(stringProperties.size(), length); |
| |
| // 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); |
| QCOMPARE(it.flags(), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); |
| 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()); |
| QCOMPARE(it.flags(), obj.propertyFlags(name)); |
| QVERIFY(it.value().strictlyEquals(obj.property(name))); |
| } |
| } |
| |
| static QScriptValue myGetterSetter(QScriptContext *ctx, QScriptEngine *) |
| { |
| if (ctx->argumentCount() == 1) |
| ctx->thisObject().setProperty("bar", ctx->argument(0)); |
| return ctx->thisObject().property("bar"); |
| } |
| |
| static QScriptValue myGetter(QScriptContext *ctx, QScriptEngine *) |
| { |
| return ctx->thisObject().property("bar"); |
| } |
| |
| static QScriptValue mySetter(QScriptContext *ctx, QScriptEngine *) |
| { |
| ctx->thisObject().setProperty("bar", ctx->argument(0)); |
| return ctx->argument(0); |
| } |
| |
| void tst_QScriptValueIterator::iterateGetterSetter() |
| { |
| // unified getter/setter function |
| { |
| QScriptEngine eng; |
| QScriptValue obj = eng.newObject(); |
| obj.setProperty("foo", eng.newFunction(myGetterSetter), |
| QScriptValue::PropertyGetter | QScriptValue::PropertySetter); |
| QScriptValue val(&eng, 123); |
| obj.setProperty("foo", val); |
| QVERIFY(obj.property("bar").strictlyEquals(val)); |
| QVERIFY(obj.property("foo").strictlyEquals(val)); |
| |
| QScriptValueIterator 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)); |
| QScriptValue 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) { |
| QScriptEngine eng; |
| QScriptValue 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); |
| } |
| QScriptValue val(&eng, 123); |
| obj.setProperty("foo", val); |
| QVERIFY(obj.property("bar").strictlyEquals(val)); |
| QVERIFY(obj.property("foo").strictlyEquals(val)); |
| |
| QScriptValueIterator it(obj); |
| QVERIFY(it.hasNext()); |
| it.next(); |
| QCOMPARE(it.name(), QString::fromLatin1("foo")); |
| QVERIFY(it.value().strictlyEquals(val)); |
| QScriptValue 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)); |
| } |
| } |
| |
| void tst_QScriptValueIterator::assignObjectToIterator() |
| { |
| QScriptEngine eng; |
| QScriptValue obj1 = eng.newObject(); |
| obj1.setProperty("foo", 123); |
| QScriptValue obj2 = eng.newObject(); |
| obj2.setProperty("bar", 456); |
| |
| QScriptValueIterator 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_QScriptValueIterator::iterateNonObject() |
| { |
| QScriptValueIterator it(123); |
| QVERIFY(!it.hasNext()); |
| it.next(); |
| QVERIFY(!it.hasPrevious()); |
| it.previous(); |
| it.toFront(); |
| it.toBack(); |
| it.name(); |
| it.scriptName(); |
| it.flags(); |
| it.value(); |
| it.setValue(1); |
| it.remove(); |
| QScriptValue num(5); |
| it = num; |
| QVERIFY(!it.hasNext()); |
| } |
| |
| void tst_QScriptValueIterator::iterateOverObjectFromDeletedEngine() |
| { |
| QScriptEngine *engine = new QScriptEngine; |
| QScriptValue 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 |
| QScriptValueIterator 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.scriptName().isValid()); |
| QVERIFY(!it.value().isValid()); |
| it.setValue("1234567"); |
| it.remove(); |
| |
| QVERIFY(!it.hasPrevious()); |
| it.previous(); |
| |
| QVERIFY(it.name().isEmpty()); |
| QVERIFY(!it.scriptName().isValid()); |
| QVERIFY(!it.value().isValid()); |
| it.setValue("1234567"); |
| it.remove(); |
| } |
| |
| QTEST_MAIN(tst_QScriptValueIterator) |
| #include "tst_qscriptvalueiterator.moc" |