Home | History | Annotate | Download | only in qscriptvalue
      1 /*
      2     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
      3 
      4     This library is free software; you can redistribute it and/or
      5     modify it under the terms of the GNU Library General Public
      6     License as published by the Free Software Foundation; either
      7     version 2 of the License, or (at your option) any later version.
      8 
      9     This library is distributed in the hope that it will be useful,
     10     but WITHOUT ANY WARRANTY; without even the implied warranty of
     11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12     Library General Public License for more details.
     13 
     14     You should have received a copy of the GNU Library General Public License
     15     along with this library; see the file COPYING.LIB.  If not, write to
     16     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17     Boston, MA 02110-1301, USA.
     18 */
     19 
     20 #include "tst_qscriptvalue.h"
     21 #include <QtCore/qnumeric.h>
     22 
     23 tst_QScriptValue::tst_QScriptValue()
     24     : m_engine(0)
     25 {
     26 }
     27 
     28 tst_QScriptValue::~tst_QScriptValue()
     29 {
     30     delete m_engine;
     31 }
     32 
     33 void tst_QScriptValue::ctor()
     34 {
     35     QScriptEngine eng;
     36     {
     37         QScriptValue v;
     38         QCOMPARE(v.isValid(), false);
     39         QCOMPARE(v.engine(), (QScriptEngine*)0);
     40     }
     41     {
     42         QScriptValue v(&eng, QScriptValue::UndefinedValue);
     43         QCOMPARE(v.isValid(), true);
     44         QCOMPARE(v.isUndefined(), true);
     45         QCOMPARE(v.isObject(), false);
     46         QCOMPARE(v.engine(), &eng);
     47     }
     48     {
     49         QScriptValue v(&eng, QScriptValue::NullValue);
     50         QCOMPARE(v.isValid(), true);
     51         QCOMPARE(v.isNull(), true);
     52         QCOMPARE(v.isObject(), false);
     53         QCOMPARE(v.engine(), &eng);
     54     }
     55     {
     56         QScriptValue v(&eng, false);
     57         QCOMPARE(v.isValid(), true);
     58         QCOMPARE(v.isBoolean(), true);
     59         QCOMPARE(v.isBool(), true);
     60         QCOMPARE(v.isObject(), false);
     61         QCOMPARE(v.toBoolean(), false);
     62         QCOMPARE(v.engine(), &eng);
     63     }
     64     {
     65         QScriptValue v(&eng, int(1));
     66         QCOMPARE(v.isValid(), true);
     67         QCOMPARE(v.isNumber(), true);
     68         QCOMPARE(v.isObject(), false);
     69         QCOMPARE(v.toNumber(), 1.0);
     70         QCOMPARE(v.engine(), &eng);
     71     }
     72     {
     73         QScriptValue v(int(0x43211234));
     74         QVERIFY(v.isNumber());
     75         QCOMPARE(v.toInt32(), 0x43211234);
     76     }
     77     {
     78         QScriptValue v(&eng, uint(1));
     79         QCOMPARE(v.isValid(), true);
     80         QCOMPARE(v.isNumber(), true);
     81         QCOMPARE(v.isObject(), false);
     82         QCOMPARE(v.toNumber(), 1.0);
     83         QCOMPARE(v.engine(), &eng);
     84     }
     85     {
     86         QScriptValue v(uint(0x43211234));
     87         QVERIFY(v.isNumber());
     88         QCOMPARE(v.toUInt32(), uint(0x43211234));
     89     }
     90     {
     91         QScriptValue v(&eng, 1.0);
     92         QCOMPARE(v.isValid(), true);
     93         QCOMPARE(v.isNumber(), true);
     94         QCOMPARE(v.isObject(), false);
     95         QCOMPARE(v.toNumber(), 1.0);
     96         QCOMPARE(v.engine(), &eng);
     97     }
     98     {
     99         QScriptValue v(12345678910.5);
    100         QVERIFY(v.isNumber());
    101         QCOMPARE(v.toNumber(), 12345678910.5);
    102     }
    103     {
    104         QScriptValue v(&eng, "ciao");
    105         QCOMPARE(v.isValid(), true);
    106         QCOMPARE(v.isString(), true);
    107         QCOMPARE(v.isObject(), false);
    108         QCOMPARE(v.toString(), QLatin1String("ciao"));
    109         QCOMPARE(v.engine(), &eng);
    110     }
    111     {
    112         QScriptValue v(&eng, QString("ciao"));
    113         QCOMPARE(v.isValid(), true);
    114         QCOMPARE(v.isString(), true);
    115         QCOMPARE(v.isObject(), false);
    116         QCOMPARE(v.toString(), QLatin1String("ciao"));
    117         QCOMPARE(v.engine(), &eng);
    118     }
    119     // copy constructor, operator=
    120     {
    121         QScriptValue v(&eng, 1.0);
    122         QScriptValue v2(v);
    123         QCOMPARE(v2.strictlyEquals(v), true);
    124         QCOMPARE(v2.engine(), &eng);
    125 
    126         QScriptValue v3(v);
    127         QCOMPARE(v3.strictlyEquals(v), true);
    128         QCOMPARE(v3.strictlyEquals(v2), true);
    129         QCOMPARE(v3.engine(), &eng);
    130 
    131         QScriptValue v4(&eng, 2.0);
    132         QCOMPARE(v4.strictlyEquals(v), false);
    133         v3 = v4;
    134         QCOMPARE(v3.strictlyEquals(v), false);
    135         QCOMPARE(v3.strictlyEquals(v4), true);
    136 
    137         v2 = QScriptValue();
    138         QCOMPARE(v2.strictlyEquals(v), false);
    139         QCOMPARE(v.toNumber(), 1.0);
    140 
    141         QScriptValue v5(v);
    142         QCOMPARE(v5.strictlyEquals(v), true);
    143         v = QScriptValue();
    144         QCOMPARE(v5.strictlyEquals(v), false);
    145         QCOMPARE(v5.toNumber(), 1.0);
    146     }
    147 
    148     // constructors that take no engine argument
    149     {
    150         QScriptValue v(QScriptValue::UndefinedValue);
    151         QCOMPARE(v.isValid(), true);
    152         QCOMPARE(v.isUndefined(), true);
    153         QCOMPARE(v.isObject(), false);
    154         QCOMPARE(v.engine(), (QScriptEngine*)0);
    155     }
    156     {
    157         QScriptValue v(QScriptValue::NullValue);
    158         QCOMPARE(v.isValid(), true);
    159         QCOMPARE(v.isNull(), true);
    160         QCOMPARE(v.isObject(), false);
    161         QCOMPARE(v.engine(), (QScriptEngine*)0);
    162     }
    163     {
    164         QScriptValue v(false);
    165         QCOMPARE(v.isValid(), true);
    166         QCOMPARE(v.isBoolean(), true);
    167         QCOMPARE(v.isBool(), true);
    168         QCOMPARE(v.isObject(), false);
    169         QCOMPARE(v.toBoolean(), false);
    170         QCOMPARE(v.engine(), (QScriptEngine*)0);
    171     }
    172     {
    173         QScriptValue v(int(1));
    174         QCOMPARE(v.isValid(), true);
    175         QCOMPARE(v.isNumber(), true);
    176         QCOMPARE(v.isObject(), false);
    177         QCOMPARE(v.toNumber(), 1.0);
    178         QCOMPARE(v.engine(), (QScriptEngine*)0);
    179     }
    180     {
    181         QScriptValue v(uint(1));
    182         QCOMPARE(v.isValid(), true);
    183         QCOMPARE(v.isNumber(), true);
    184         QCOMPARE(v.isObject(), false);
    185         QCOMPARE(v.toNumber(), 1.0);
    186         QCOMPARE(v.engine(), (QScriptEngine*)0);
    187     }
    188     {
    189         QScriptValue v(1.0);
    190         QCOMPARE(v.isValid(), true);
    191         QCOMPARE(v.isNumber(), true);
    192         QCOMPARE(v.isObject(), false);
    193         QCOMPARE(v.toNumber(), 1.0);
    194         QCOMPARE(v.engine(), (QScriptEngine*)0);
    195     }
    196     {
    197         QScriptValue v("ciao");
    198         QCOMPARE(v.isValid(), true);
    199         QCOMPARE(v.isString(), true);
    200         QCOMPARE(v.isObject(), false);
    201         QCOMPARE(v.toString(), QLatin1String("ciao"));
    202         QCOMPARE(v.engine(), (QScriptEngine*)0);
    203     }
    204     {
    205         QScriptValue v(QString("ciao"));
    206         QCOMPARE(v.isValid(), true);
    207         QCOMPARE(v.isString(), true);
    208         QCOMPARE(v.isObject(), false);
    209         QCOMPARE(v.toString(), QLatin1String("ciao"));
    210         QCOMPARE(v.engine(), (QScriptEngine*)0);
    211     }
    212     // copy constructor, operator=
    213     {
    214         QScriptValue v(1.0);
    215         QScriptValue v2(v);
    216         QCOMPARE(v2.strictlyEquals(v), true);
    217         QCOMPARE(v2.engine(), (QScriptEngine*)0);
    218 
    219         QScriptValue v3(v);
    220         QCOMPARE(v3.strictlyEquals(v), true);
    221         QCOMPARE(v3.strictlyEquals(v2), true);
    222         QCOMPARE(v3.engine(), (QScriptEngine*)0);
    223 
    224         QScriptValue v4(2.0);
    225         QCOMPARE(v4.strictlyEquals(v), false);
    226         v3 = v4;
    227         QCOMPARE(v3.strictlyEquals(v), false);
    228         QCOMPARE(v3.strictlyEquals(v4), true);
    229 
    230         v2 = QScriptValue();
    231         QCOMPARE(v2.strictlyEquals(v), false);
    232         QCOMPARE(v.toNumber(), 1.0);
    233 
    234         QScriptValue v5(v);
    235         QCOMPARE(v5.strictlyEquals(v), true);
    236         v = QScriptValue();
    237         QCOMPARE(v5.strictlyEquals(v), false);
    238         QCOMPARE(v5.toNumber(), 1.0);
    239     }
    240 
    241     // 0 engine
    242     QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
    243     QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
    244     QVERIFY(QScriptValue(0, false).isBool());
    245     QVERIFY(QScriptValue(0, int(1)).isNumber());
    246     QVERIFY(QScriptValue(0, uint(1)).isNumber());
    247     QVERIFY(QScriptValue(0, 1.0).isNumber());
    248     QVERIFY(QScriptValue(0, "ciao").isString());
    249     QVERIFY(QScriptValue(0, QString("ciao")).isString());
    250 }
    251 
    252 void tst_QScriptValue::getPropertySimple_data()
    253 {
    254     QTest::addColumn<QString>("code");
    255     QTest::addColumn<QString>("propertyName");
    256     QTest::addColumn<QString>("desc");
    257     QTest::addColumn<bool>("isArrayIndex");
    258 
    259     QTest::newRow("new Array()")
    260             << QString::fromAscii("new Array()")
    261             << QString::fromAscii("length")
    262             << QString::fromAscii("0")
    263             << false;
    264     QTest::newRow("new Object().length")
    265             << QString::fromAscii("new Object()")
    266             << QString::fromAscii("length")
    267             << QString::fromAscii("") // Undefined is an invalid property.
    268             << false;
    269     QTest::newRow("new Object().toString")
    270             << QString::fromAscii("new Object()")
    271             << QString::fromAscii("toString")
    272             << QString::fromAscii("function toString() {\n    [native code]\n}")
    273             << false;
    274     QTest::newRow("[1,2,3,4]")
    275             << QString::fromAscii("[1,2,3,'s',4]")
    276             << QString::fromAscii("2")
    277             << QString::fromAscii("3")
    278             << true;
    279     QTest::newRow("[1,3,'a','b']")
    280             << QString::fromAscii("[1,3,'a','b']")
    281             << QString::fromAscii("3")
    282             << QString::fromAscii("b")
    283             << true;
    284     QTest::newRow("[4,5]")
    285             << QString::fromAscii("[4,5]")
    286             << QString::fromAscii("123")
    287             << QString::fromAscii("") // Undefined is an invalid property.
    288             << true;
    289     QTest::newRow("[1,3,4]")
    290             << QString::fromAscii("[1,3,4]")
    291             << QString::fromAscii("abc")
    292             << QString::fromAscii("") // Undefined is an invalid property.
    293             << true;
    294 }
    295 
    296 void tst_QScriptValue::getPropertySimple()
    297 {
    298     QFETCH(QString, code);
    299     QFETCH(QString, propertyName);
    300     QFETCH(QString, desc);
    301 
    302     QScriptEngine engine;
    303     QScriptValue object = engine.evaluate(code);
    304     QVERIFY(object.isValid());
    305     {
    306         QScriptValue property = object.property(propertyName);
    307         QCOMPARE(property.toString(), desc);
    308     }
    309     {
    310         QScriptString name = engine.toStringHandle(propertyName);
    311         QScriptValue property = object.property(name);
    312         QCOMPARE(property.toString(), desc);
    313     }
    314     {
    315         bool ok;
    316         quint32 idx = engine.toStringHandle(propertyName).toArrayIndex(&ok);
    317         if (ok) {
    318             QScriptValue property = object.property(idx);
    319             QCOMPARE(property.toString(), desc);
    320         }
    321     }
    322 }
    323 
    324 void tst_QScriptValue::setPropertySimple()
    325 {
    326     QScriptEngine engine;
    327     {
    328         QScriptValue invalid;
    329         QScriptValue property(1234);
    330 
    331         invalid.setProperty("aaa", property);
    332         invalid.setProperty(13, property);
    333         invalid.setProperty(engine.toStringHandle("aaa"), property);
    334 
    335         QVERIFY(!invalid.property("aaa").isValid());
    336         QVERIFY(!invalid.property(13).isValid());
    337         QVERIFY(!invalid.property(engine.toStringHandle("aaa")).isValid());
    338     }
    339     {
    340         QScriptValue object = engine.newObject();
    341         QScriptValue property;
    342 
    343         object.setProperty(13, property);
    344         object.setProperty("aaa", property);
    345         object.setProperty(engine.toStringHandle("aaa"), property);
    346 
    347         QVERIFY(!object.property(13).isValid());
    348         QVERIFY(!object.property("aaa").isValid());
    349         QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid());
    350     }
    351     {
    352         // Check if setting an invalid property works as deleteProperty.
    353         QScriptValue object = engine.evaluate("o = {13: 0, 'aaa': 3, 'bbb': 1}");
    354         QScriptValue property;
    355 
    356         QVERIFY(object.property(13).isValid());
    357         QVERIFY(object.property("aaa").isValid());
    358         QVERIFY(object.property(engine.toStringHandle("aaa")).isValid());
    359 
    360         object.setProperty(13, property);
    361         object.setProperty("aaa", property);
    362         object.setProperty(engine.toStringHandle("bbb"), property);
    363 
    364         QVERIFY(!object.property(13).isValid());
    365         QVERIFY(!object.property("aaa").isValid());
    366         QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid());
    367     }
    368     {
    369         QScriptValue object = engine.evaluate("new Object");
    370         QVERIFY(object.isObject());
    371         QScriptValue property = object.property("foo");
    372         QVERIFY(!property.isValid());
    373         property = QScriptValue(2);
    374         object.setProperty("foo", property);
    375         QVERIFY(object.property("foo").isNumber());
    376         QVERIFY(object.property("foo").toNumber() == 2);
    377     }
    378     {
    379         QScriptValue o1 = engine.evaluate("o1 = new Object; o1");
    380         QScriptValue o2 = engine.evaluate("o2 = new Object; o2");
    381         QVERIFY(engine.evaluate("o1.__proto__ = o2; o1.__proto__ === o2").toBool());
    382         QVERIFY(engine.evaluate("o2.foo = 22; o1.foo == 22").toBool());
    383         QVERIFY(o1.property("foo").toString() == "22");
    384         o2.setProperty("foo", QScriptValue(&engine, 456.0));
    385         QVERIFY(engine.evaluate("o1.foo == 456").toBool());
    386         QVERIFY(o1.property("foo").isNumber());
    387     }
    388 }
    389 
    390 void tst_QScriptValue::getPropertyResolveFlag()
    391 {
    392     QScriptEngine engine;
    393     QScriptValue object1 = engine.evaluate("o1 = new Object();");
    394     QScriptValue object2 = engine.evaluate("o2 = new Object(); o1.__proto__ = o2; o2");
    395     QScriptValue number(&engine, 456.0);
    396     QVERIFY(object1.isObject());
    397     QVERIFY(object2.isObject());
    398     QVERIFY(number.isNumber());
    399 
    400     object2.setProperty("propertyInPrototype", number);
    401     QVERIFY(object2.property("propertyInPrototype").isNumber());
    402     // default is ResolvePrototype
    403     QCOMPARE(object1.property("propertyInPrototype").strictlyEquals(number), true);
    404     QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolvePrototype)
    405              .strictlyEquals(number), true);
    406     QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolveLocal).isValid(), false);
    407 }
    408 
    409 void tst_QScriptValue::getSetProperty()
    410 {
    411     QScriptEngine eng;
    412 
    413     QScriptValue object = eng.newObject();
    414 
    415     QScriptValue str = QScriptValue(&eng, "bar");
    416     object.setProperty("foo", str);
    417     QCOMPARE(object.property("foo").toString(), str.toString());
    418 
    419     QScriptValue num = QScriptValue(&eng, 123.0);
    420     object.setProperty("baz", num);
    421     QCOMPARE(object.property("baz").toNumber(), num.toNumber());
    422 
    423     QScriptValue strstr = QScriptValue("bar");
    424     QCOMPARE(strstr.engine(), (QScriptEngine *)0);
    425     object.setProperty("foo", strstr);
    426     QCOMPARE(object.property("foo").toString(), strstr.toString());
    427     QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
    428 
    429     QScriptValue numnum = QScriptValue(123.0);
    430     object.setProperty("baz", numnum);
    431     QCOMPARE(object.property("baz").toNumber(), numnum.toNumber());
    432 
    433     QScriptValue inv;
    434     inv.setProperty("foo", num);
    435     QCOMPARE(inv.property("foo").isValid(), false);
    436 
    437     QScriptValue array = eng.newArray();
    438     array.setProperty(0, num);
    439     QCOMPARE(array.property(0).toNumber(), num.toNumber());
    440     QCOMPARE(array.property("0").toNumber(), num.toNumber());
    441     QCOMPARE(array.property("length").toUInt32(), quint32(1));
    442     array.setProperty(1, str);
    443     QCOMPARE(array.property(1).toString(), str.toString());
    444     QCOMPARE(array.property("1").toString(), str.toString());
    445     QCOMPARE(array.property("length").toUInt32(), quint32(2));
    446     array.setProperty("length", QScriptValue(&eng, 1));
    447     QCOMPARE(array.property("length").toUInt32(), quint32(1));
    448     QCOMPARE(array.property(1).isValid(), false);
    449 
    450     // task 162051 -- detecting whether the property is an array index or not
    451     QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123)));
    452     QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
    453     QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QScriptValue(&eng, true)));
    454     QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QScriptValue(&eng, false)));
    455     QVERIFY(eng.evaluate("a[0]").isUndefined());
    456     QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QScriptValue(&eng, 456)));
    457     QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
    458     QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QScriptValue(&eng, true)));
    459     QVERIFY(eng.evaluate("a[0]").isUndefined());
    460     QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789)));
    461     QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1)));
    462 
    463     // task 183072 -- 0x800000000 is not an array index
    464     eng.evaluate("a = []; a[0x800000000] = 123");
    465     QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
    466     QVERIFY(eng.evaluate("a[0]").isUndefined());
    467     QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123)));
    468 
    469     QScriptEngine otherEngine;
    470     QScriptValue otherNum = QScriptValue(&otherEngine, 123);
    471     QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: cannot set value created in a different engine");
    472     object.setProperty("oof", otherNum);
    473     QCOMPARE(object.property("oof").isValid(), false);
    474 
    475     // test ResolveMode
    476     QScriptValue object2 = eng.newObject();
    477     object.setPrototype(object2);
    478     QScriptValue num2 = QScriptValue(&eng, 456.0);
    479     object2.setProperty("propertyInPrototype", num2);
    480     // default is ResolvePrototype
    481     QCOMPARE(object.property("propertyInPrototype")
    482              .strictlyEquals(num2), true);
    483     QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolvePrototype)
    484              .strictlyEquals(num2), true);
    485     QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveLocal)
    486              .isValid(), false);
    487     QEXPECT_FAIL("", "QScriptValue::ResolveScope is not implemented", Continue);
    488     QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveScope)
    489              .strictlyEquals(num2), false);
    490     QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull)
    491              .strictlyEquals(num2), true);
    492 
    493     // test property removal (setProperty(QScriptValue()))
    494     QScriptValue object3 = eng.newObject();
    495     object3.setProperty("foo", num);
    496     QCOMPARE(object3.property("foo").strictlyEquals(num), true);
    497     object3.setProperty("bar", str);
    498     QCOMPARE(object3.property("bar").strictlyEquals(str), true);
    499     object3.setProperty("foo", QScriptValue());
    500     QCOMPARE(object3.property("foo").isValid(), false);
    501     QCOMPARE(object3.property("bar").strictlyEquals(str), true);
    502     object3.setProperty("foo", num);
    503     QCOMPARE(object3.property("foo").strictlyEquals(num), true);
    504     QCOMPARE(object3.property("bar").strictlyEquals(str), true);
    505     object3.setProperty("bar", QScriptValue());
    506     QCOMPARE(object3.property("bar").isValid(), false);
    507     QCOMPARE(object3.property("foo").strictlyEquals(num), true);
    508     object3.setProperty("foo", QScriptValue());
    509     object3.setProperty("foo", QScriptValue());
    510 
    511     eng.globalObject().setProperty("object3", object3);
    512     QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
    513              .strictlyEquals(QScriptValue(&eng, false)), true);
    514     object3.setProperty("foo", num);
    515     QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
    516              .strictlyEquals(QScriptValue(&eng, true)), true);
    517     eng.globalObject().setProperty("object3", QScriptValue());
    518     QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')")
    519              .strictlyEquals(QScriptValue(&eng, false)), true);
    520 
    521     eng.globalObject().setProperty("object", object);
    522 
    523     // ReadOnly
    524     object.setProperty("readOnlyProperty", num, QScriptValue::ReadOnly);
    525     // QCOMPARE(object.propertyFlags("readOnlyProperty"), QScriptValue::ReadOnly);
    526     QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
    527     eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty");
    528     QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
    529     // Should still be part of enumeration.
    530     {
    531         QScriptValue ret = eng.evaluate(
    532             "found = false;"
    533             "for (var p in object) {"
    534             "  if (p == 'readOnlyProperty') {"
    535             "    found = true; break;"
    536             "  }"
    537             "} found");
    538         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
    539     }
    540     // should still be deletable
    541     {
    542         QScriptValue ret = eng.evaluate("delete object.readOnlyProperty");
    543         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
    544         QCOMPARE(object.property("readOnlyProperty").isValid(), false);
    545     }
    546 
    547     // Undeletable
    548     object.setProperty("undeletableProperty", num, QScriptValue::Undeletable);
    549     // QCOMPARE(object.propertyFlags("undeletableProperty"), QScriptValue::Undeletable);
    550     QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
    551     {
    552         QScriptValue ret = eng.evaluate("delete object.undeletableProperty");
    553         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), false);
    554         QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
    555     }
    556     // should still be writable
    557     eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1");
    558     QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1);
    559     // should still be part of enumeration
    560     {
    561         QScriptValue ret = eng.evaluate(
    562             "found = false;"
    563             "for (var p in object) {"
    564             "  if (p == 'undeletableProperty') {"
    565             "    found = true; break;"
    566             "  }"
    567             "} found");
    568         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
    569     }
    570     // should still be deletable from C++
    571     object.setProperty("undeletableProperty", QScriptValue());
    572     QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
    573     QVERIFY(!object.property("undeletableProperty").isValid());
    574     // QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
    575     // QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
    576 
    577     // SkipInEnumeration
    578     object.setProperty("dontEnumProperty", num, QScriptValue::SkipInEnumeration);
    579     // QCOMPARE(object.propertyFlags("dontEnumProperty"), QScriptValue::SkipInEnumeration);
    580     QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true);
    581     // should not be part of enumeration
    582     {
    583         QScriptValue ret = eng.evaluate(
    584             "found = false;"
    585             "for (var p in object) {"
    586             "  if (p == 'dontEnumProperty') {"
    587             "    found = true; break;"
    588             "  }"
    589             "} found");
    590         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, false)), true);
    591     }
    592     // should still be writable
    593     eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1");
    594     QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1);
    595     // should still be deletable
    596     {
    597         QScriptValue ret = eng.evaluate("delete object.dontEnumProperty");
    598         QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
    599         QCOMPARE(object.property("dontEnumProperty").isValid(), false);
    600     }
    601 
    602     // change flags
    603     object.setProperty("flagProperty", str);
    604     // QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QScriptValue::PropertyFlags>(0));
    605 
    606     object.setProperty("flagProperty", str, QScriptValue::ReadOnly);
    607     // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly);
    608 
    609     // object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QScriptValue::SkipInEnumeration);
    610     // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
    611 
    612     object.setProperty("flagProperty", str, QScriptValue::KeepExistingFlags);
    613     // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
    614 
    615     object.setProperty("flagProperty", str, QScriptValue::UserRange);
    616     // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::UserRange);
    617 
    618     // flags of property in the prototype
    619     {
    620         QScriptValue object2 = eng.newObject();
    621         object2.setPrototype(object);
    622         // QCOMPARE(object2.propertyFlags("flagProperty", QScriptValue::ResolveLocal), 0);
    623         // QCOMPARE(object2.propertyFlags("flagProperty"), QScriptValue::UserRange);
    624     }
    625 
    626     // using interned strings
    627     QScriptString foo = eng.toStringHandle("foo");
    628 
    629     object.setProperty(foo, QScriptValue());
    630     QVERIFY(!object.property(foo).isValid());
    631 
    632     object.setProperty(foo, num);
    633     QVERIFY(object.property(foo).strictlyEquals(num));
    634     QVERIFY(object.property("foo").strictlyEquals(num));
    635     // QVERIFY(object.propertyFlags(foo) == 0);
    636 }
    637 
    638 void tst_QScriptValue::toStringSimple_data()
    639 {
    640     QTest::addColumn<QString>("code");
    641     QTest::addColumn<QString>("result");
    642 
    643     QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello");
    644     QTest::newRow("string utf") << QString::fromUtf8("''") << QString::fromUtf8("");
    645     QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5");
    646     QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null");
    647     QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false");
    648     QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined");
    649     QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]");
    650 }
    651 
    652 /* Test conversion to string from different JSC types */
    653 void tst_QScriptValue::toStringSimple()
    654 {
    655     QFETCH(QString, code);
    656     QFETCH(QString, result);
    657 
    658     QScriptEngine engine;
    659     QCOMPARE(engine.evaluate(code).toString(), result);
    660 }
    661 
    662 void tst_QScriptValue::copyConstructor_data()
    663 {
    664     QScriptEngine engine;
    665     QScriptValue nnumber(123);
    666     QScriptValue nstring("ping");
    667     QScriptValue number(engine.evaluate("1"));
    668     QScriptValue string(engine.evaluate("'foo'"));
    669     QScriptValue object(engine.evaluate("new Object"));
    670     QScriptValue undefined(engine.evaluate("undefined"));
    671     QScriptValue null(engine.evaluate("null"));
    672 
    673     QTest::addColumn<QScriptValue>("value");
    674     QTest::addColumn<QString>("result");
    675 
    676     QTest::newRow("native number") << nnumber << QString::number(123);
    677     QTest::newRow("native string") << nstring << QString("ping");
    678     QTest::newRow("number") << number << QString::fromAscii("1");
    679     QTest::newRow("string") << string << QString::fromAscii("foo");
    680     QTest::newRow("object") << object << QString::fromAscii("[object Object]");
    681     QTest::newRow("undefined") << undefined << QString::fromAscii("undefined");
    682     QTest::newRow("null") << null << QString::fromAscii("null");
    683 }
    684 
    685 void tst_QScriptValue::copyConstructor()
    686 {
    687     QFETCH(QScriptValue, value);
    688     QFETCH(QString, result);
    689 
    690     QVERIFY(value.isValid());
    691     QScriptValue tmp(value);
    692     QVERIFY(tmp.isValid());
    693     QCOMPARE(tmp.toString(), result);
    694 }
    695 
    696 void tst_QScriptValue::assignOperator_data()
    697 {
    698     copyConstructor_data();
    699 }
    700 
    701 void tst_QScriptValue::assignOperator()
    702 {
    703     QFETCH(QScriptValue, value);
    704     QFETCH(QString, result);
    705 
    706     QScriptValue tmp;
    707     tmp = value;
    708     QVERIFY(tmp.isValid());
    709     QCOMPARE(tmp.toString(), result);
    710 }
    711 
    712 /* Test internal data sharing between a diffrenet QScriptValue. */
    713 void tst_QScriptValue::dataSharing()
    714 {
    715     QScriptEngine engine;
    716     QScriptValue v1;
    717     QScriptValue v2(v1);
    718 
    719     v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid.
    720     QVERIFY(v1.isValid());
    721     QVERIFY(!v2.isValid());
    722 
    723     v2 = v1; // v1 == 1; v2 == 1.
    724     QVERIFY(v1.isValid());
    725     QVERIFY(v2.isValid());
    726 
    727     v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1.
    728     QVERIFY(v1.isValid());
    729     QVERIFY(v2.isValid());
    730     QVERIFY(v2.toString() != v1.toString());
    731 
    732     // TODO add object manipulation (v1 and v2 point to the same object).
    733 }
    734 
    735 void tst_QScriptValue::constructors_data()
    736 {
    737     QScriptEngine engine;
    738 
    739     QTest::addColumn<QScriptValue>("value");
    740     QTest::addColumn<QString>("string");
    741     QTest::addColumn<bool>("valid");
    742     QTest::addColumn<bool>("object");
    743 
    744     QTest::newRow("invalid") << QScriptValue() << QString() << false << false;
    745     QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false;
    746     QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false;
    747     QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false;
    748     QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false;
    749     QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true;
    750     QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false;
    751     QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false;
    752 }
    753 
    754 void tst_QScriptValue::constructors()
    755 {
    756     QFETCH(QScriptValue, value);
    757     QFETCH(QString, string);
    758     QFETCH(bool, valid);
    759     QFETCH(bool, object);
    760 
    761     QCOMPARE(value.isValid(), valid);
    762     QCOMPARE(value.toString(), string);
    763     QCOMPARE(value.isObject(), object);
    764 }
    765 
    766 void tst_QScriptValue::call()
    767 {
    768     QScriptEngine engine;
    769     QScriptValue ping = engine.evaluate("( function() {return 'ping';} )");
    770     QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )");
    771     QScriptValue one(1);
    772     QScriptValue five(5);
    773     QScriptValue result;
    774 
    775     QVERIFY(one.isValid());
    776     QVERIFY(five.isValid());
    777 
    778     QVERIFY(ping.isValid());
    779     QVERIFY(ping.isFunction());
    780     result = ping.call();
    781     QVERIFY(result.isValid());
    782     QCOMPARE(result.toString(), QString::fromUtf8("ping"));
    783 
    784     QVERIFY(incr.isValid());
    785     QVERIFY(incr.isFunction());
    786     result = incr.call(QScriptValue(), QScriptValueList() << one);
    787     QVERIFY(result.isValid());
    788     QCOMPARE(result.toString(), QString("2"));
    789 
    790     QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6"));
    791 
    792     QVERIFY(incr.call().isValid()); // Exception.
    793 }
    794 
    795 void tst_QScriptValue::getSetPrototype()
    796 {
    797     QScriptEngine engine;
    798     QScriptValue object = engine.evaluate("new Object()");
    799     QScriptValue object2 = engine.evaluate("new Object()");
    800     object2.setPrototype(object);
    801     QCOMPARE(object2.prototype().strictlyEquals(object), true);
    802 
    803     QScriptValue inv;
    804     inv.setPrototype(object);
    805     QCOMPARE(inv.prototype().isValid(), false);
    806 
    807     QScriptEngine otherEngine;
    808     QScriptValue object3 = otherEngine.evaluate("new Object()");
    809     QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
    810     object2.setPrototype(object3);
    811     QCOMPARE(object2.prototype().strictlyEquals(object), true);
    812 
    813     // cyclic prototypes
    814     {
    815         QScriptValue ret = engine.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
    816         QCOMPARE(ret.isError(), true);
    817         QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
    818     }
    819     {
    820         QScriptValue ret = engine.evaluate("p.__proto__ = { }");
    821         QCOMPARE(ret.isError(), false);
    822     }
    823 
    824     QScriptValue old = object.prototype();
    825     QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
    826     object.setPrototype(object);
    827     QCOMPARE(object.prototype().strictlyEquals(old), true);
    828 
    829     object2.setPrototype(object);
    830     QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
    831     object.setPrototype(object2);
    832     QCOMPARE(object.prototype().strictlyEquals(old), true);
    833 }
    834 
    835 void tst_QScriptValue::toObjectSimple()
    836 {
    837     QScriptEngine eng;
    838 
    839     QScriptValue undefined = eng.undefinedValue();
    840     QCOMPARE(undefined.toObject().isValid(), false);
    841     QScriptValue null = eng.nullValue();
    842     QCOMPARE(null.toObject().isValid(), false);
    843     QCOMPARE(QScriptValue().toObject().isValid(), false);
    844 
    845     QScriptValue falskt = QScriptValue(&eng, false);
    846     {
    847         QScriptValue tmp = falskt.toObject();
    848         QCOMPARE(tmp.isObject(), true);
    849         QCOMPARE(falskt.isObject(), false);
    850         QCOMPARE(tmp.toNumber(), falskt.toNumber());
    851     }
    852 
    853     QScriptValue sant = QScriptValue(&eng, true);
    854     {
    855         QScriptValue tmp = sant.toObject();
    856         QCOMPARE(tmp.isObject(), true);
    857         QCOMPARE(sant.isObject(), false);
    858         QCOMPARE(tmp.toNumber(), sant.toNumber());
    859     }
    860 
    861     QScriptValue number = QScriptValue(&eng, 123.0);
    862     {
    863         QScriptValue tmp = number.toObject();
    864         QCOMPARE(tmp.isObject(), true);
    865         QCOMPARE(number.isObject(), false);
    866         QCOMPARE(tmp.toNumber(), number.toNumber());
    867     }
    868 
    869     QScriptValue str = QScriptValue(&eng, QString("ciao"));
    870     {
    871         QScriptValue tmp = str.toObject();
    872         QCOMPARE(tmp.isObject(), true);
    873         QCOMPARE(str.isObject(), false);
    874         QCOMPARE(tmp.toString(), str.toString());
    875     }
    876 
    877 
    878     QScriptValue object = eng.evaluate("new Object");
    879     {
    880         QScriptValue tmp = object.toObject();
    881         QVERIFY(tmp.strictlyEquals(object));
    882         QCOMPARE(tmp.isObject(), true);
    883     }
    884 
    885 
    886     // V2 constructors: in this case, you have to use QScriptEngine::toObject()
    887     {
    888         QScriptValue undefined = QScriptValue(QScriptValue::UndefinedValue);
    889         QVERIFY(!undefined.toObject().isValid());
    890         QVERIFY(!eng.toObject(undefined).isValid());
    891         QVERIFY(!undefined.engine());
    892 
    893         QScriptValue null = QScriptValue(QScriptValue::NullValue);
    894         QVERIFY(!null.toObject().isValid());
    895         QVERIFY(!eng.toObject(null).isValid());
    896         QVERIFY(!null.engine());
    897 
    898         QScriptValue falskt = QScriptValue(false);
    899         QVERIFY(!falskt.toObject().isValid());
    900         QCOMPARE(falskt.isObject(), false);
    901         QVERIFY(!falskt.engine());
    902         {
    903             QScriptValue tmp = eng.toObject(falskt);
    904             QVERIFY(tmp.isObject());
    905             QVERIFY(tmp.toBool());
    906             QVERIFY(!falskt.isObject());
    907         }
    908 
    909         QScriptValue sant = QScriptValue(true);
    910         QVERIFY(!sant.toObject().isValid());
    911         QCOMPARE(sant.isObject(), false);
    912         QVERIFY(!sant.engine());
    913         {
    914             QScriptValue tmp = eng.toObject(sant);
    915             QVERIFY(tmp.isObject());
    916             QVERIFY(tmp.toBool());
    917             QVERIFY(!sant.isObject());
    918         }
    919 
    920         QScriptValue number = QScriptValue(123.0);
    921         QVERIFY(!number.toObject().isValid());
    922         QVERIFY(!number.engine());
    923         QCOMPARE(number.isObject(), false);
    924         {
    925             QScriptValue tmp = eng.toObject(number);
    926             QVERIFY(tmp.isObject());
    927             QCOMPARE(tmp.toInt32(), number.toInt32());
    928             QVERIFY(!number.isObject());
    929         }
    930 
    931         QScriptValue str = QScriptValue(QString::fromLatin1("ciao"));
    932         QVERIFY(!str.toObject().isValid());
    933         QVERIFY(!str.engine());
    934         QCOMPARE(str.isObject(), false);
    935         {
    936             QScriptValue tmp = eng.toObject(str);
    937             QVERIFY(tmp.isObject());
    938             QCOMPARE(tmp.toString(), QString::fromLatin1("ciao"));
    939             QVERIFY(!str.isObject());
    940         }
    941     }
    942 }
    943 
    944 void tst_QScriptValue::setProperty_data()
    945 {
    946     QTest::addColumn<QScriptValue>("property");
    947     QTest::addColumn<int>("flag");
    948 
    949     QTest::newRow("int + keepExistingFlags") << QScriptValue(123456) << static_cast<int>(QScriptValue::KeepExistingFlags);
    950     QTest::newRow("int + undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::Undeletable);
    951     QTest::newRow("int + readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly);
    952     QTest::newRow("int + readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable);
    953     QTest::newRow("int + skipInEnumeration") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration);
    954     QTest::newRow("int + skipInEnumeration|readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
    955     QTest::newRow("int + skipInEnumeration|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
    956     QTest::newRow("int + skipInEnumeration|readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly | QScriptValue::Undeletable);
    957 }
    958 
    959 void tst_QScriptValue::setProperty()
    960 {
    961     QFETCH(QScriptValue, property);
    962     QFETCH(int, flag);
    963     QScriptValue::PropertyFlags flags = static_cast<QScriptValue::PropertyFlag>(flag);
    964 
    965     QScriptEngine engine;
    966     QScriptValue object = engine.evaluate("o = new Object; o");
    967     QScriptValue proto = engine.evaluate("p = new Object; o.__proto__ = p; p");
    968     engine.evaluate("o.defined1 = 1");
    969     engine.evaluate("o.defined2 = 1");
    970     engine.evaluate("o[5] = 1");
    971     engine.evaluate("p.overloaded1 = 1");
    972     engine.evaluate("o.overloaded1 = 2");
    973     engine.evaluate("p[6] = 1");
    974     engine.evaluate("o[6] = 2");
    975     engine.evaluate("p.overloaded2 = 1");
    976     engine.evaluate("o.overloaded2 = 2");
    977     engine.evaluate("p.overloaded3 = 1");
    978     engine.evaluate("o.overloaded3 = 2");
    979     engine.evaluate("p[7] = 1");
    980     engine.evaluate("o[7] = 2");
    981     engine.evaluate("p.overloaded4 = 1");
    982     engine.evaluate("o.overloaded4 = 2");
    983 
    984     // tries to set undefined property directly on object.
    985     object.setProperty(QString::fromAscii("undefined1"), property, flags);
    986     QVERIFY(engine.evaluate("o.undefined1").strictlyEquals(property));
    987     object.setProperty(engine.toStringHandle("undefined2"), property, flags);
    988     QVERIFY(object.property("undefined2").strictlyEquals(property));
    989     object.setProperty(4, property, flags);
    990     QVERIFY(object.property(4).strictlyEquals(property));
    991 
    992     // tries to set defined property directly on object
    993     object.setProperty("defined1", property, flags);
    994     QVERIFY(engine.evaluate("o.defined1").strictlyEquals(property));
    995     object.setProperty(engine.toStringHandle("defined2"), property, flags);
    996     QVERIFY(object.property("defined2").strictlyEquals(property));
    997     object.setProperty(5, property, flags);
    998     QVERIFY(object.property(5).strictlyEquals(property));
    999 
   1000     // tries to set overloaded property directly on object
   1001     object.setProperty("overloaded1", property, flags);
   1002     QVERIFY(engine.evaluate("o.overloaded1").strictlyEquals(property));
   1003     object.setProperty(engine.toStringHandle("overloaded2"), property, flags);
   1004     QVERIFY(object.property("overloaded2").strictlyEquals(property));
   1005     object.setProperty(6, property, flags);
   1006     QVERIFY(object.property(6).strictlyEquals(property));
   1007 
   1008     // tries to set overloaded property directly on prototype
   1009     proto.setProperty("overloaded3", property, flags);
   1010     QVERIFY(!engine.evaluate("o.overloaded3").strictlyEquals(property));
   1011     proto.setProperty(engine.toStringHandle("overloaded4"), property, flags);
   1012     QVERIFY(!object.property("overloaded4").strictlyEquals(property));
   1013     proto.setProperty(7, property, flags);
   1014     QVERIFY(!object.property(7).strictlyEquals(property));
   1015 
   1016     // tries to set undefined property directly on prototype
   1017     proto.setProperty("undefined3", property, flags);
   1018     QVERIFY(engine.evaluate("o.undefined3").strictlyEquals(property));
   1019     proto.setProperty(engine.toStringHandle("undefined4"), property, flags);
   1020     QVERIFY(object.property("undefined4").strictlyEquals(property));
   1021     proto.setProperty(8, property, flags);
   1022     QVERIFY(object.property(8).strictlyEquals(property));
   1023 
   1024     bool readOnly = flags & QScriptValue::ReadOnly;
   1025     bool skipInEnumeration = flags & QScriptValue::SkipInEnumeration;
   1026     bool undeletable = flags & QScriptValue::Undeletable;
   1027 
   1028     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').writable").toBool());
   1029     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1030     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1031     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1032     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1033     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').writable").toBool());
   1034     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1035     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1036     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1037     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1038     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').writable").toBool());
   1039     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1040     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1041     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1042     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1043     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').writable").toBool());
   1044     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').writable").toBool());
   1045     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').writable").toBool());
   1046     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').writable").toBool());
   1047     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').writable").toBool());
   1048     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').writable").toBool());
   1049     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1050     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1051     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1052     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1053     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').writable").toBool());
   1054     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1055     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1056     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1057     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1058     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').writable").toBool());
   1059     QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool());
   1060     QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool());
   1061     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1062     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1063     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1064     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1065     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').writable").toBool());
   1066     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1067     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1068     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1069     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1070     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').writable").toBool());
   1071     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1072     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1073     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1074     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1075     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').writable").toBool());
   1076     QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1077     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1078     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1079     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1080     QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').writable").toBool());
   1081     QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded3').writable").toBool());
   1082     QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded4').writable").toBool());
   1083 
   1084     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').configurable").toBool());
   1085     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1086     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1087     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1088     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1089     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').configurable").toBool());
   1090     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1091     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1092     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1093     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1094     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').configurable").toBool());
   1095     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1096     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1097     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1098     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1099     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').configurable").toBool());
   1100     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').configurable").toBool());
   1101     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').configurable").toBool());
   1102     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').configurable").toBool());
   1103     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').configurable").toBool());
   1104     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').configurable").toBool());
   1105     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1106     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1107     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1108     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1109     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').configurable").toBool());
   1110     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1111     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1112     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1113     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1114     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').configurable").toBool());
   1115     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1116     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1117     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1118     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1119     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').configurable").toBool());
   1120     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1121     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1122     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1123     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1124     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').configurable").toBool());
   1125     QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded1').configurable").toBool());
   1126     QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded2').configurable").toBool());
   1127     QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded3').configurable").toBool());
   1128     QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded4').configurable").toBool());
   1129     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1130     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1131     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1132     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1133     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').configurable").toBool());
   1134     QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1135     QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1136     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1137     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1138     QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').configurable").toBool());
   1139 
   1140     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '4').enumerable").toBool());
   1141     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1142     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1143     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1144     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1145     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '5').enumerable").toBool());
   1146     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1147     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1148     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1149     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1150     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '6').enumerable").toBool());
   1151     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1152     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1153     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1154     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1155     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '7').enumerable").toBool());
   1156     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '8').enumerable").toBool());
   1157     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined1').enumerable").toBool());
   1158     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined2').enumerable").toBool());
   1159     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined3').enumerable").toBool());
   1160     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined4').enumerable").toBool());
   1161     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1162     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1163     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1164     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1165     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded1').enumerable").toBool());
   1166     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1167     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1168     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1169     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1170     QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded2').enumerable").toBool());
   1171     QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded1')").toBool());
   1172     QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded2')").toBool());
   1173     QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded3')").toBool());
   1174     QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded4')").toBool());
   1175     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1176     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1177     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1178     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1179     QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded3')").toBool());
   1180     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1181     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1182     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1183     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1184     QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded4')").toBool());
   1185     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1186     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1187     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1188     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1189     QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined1')").toBool());
   1190     QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1191     QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1192     QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1193     QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
   1194     QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined2')").toBool());
   1195 }
   1196 
   1197 void tst_QScriptValue::propertyFlag_data()
   1198 {
   1199     QTest::addColumn<QString>("name");
   1200     QTest::addColumn<int>("flag");
   1201 
   1202     QTest::newRow("?Cr@jzi!%$") << "?Cr@jzi!%$" << static_cast<int>(0);
   1203     QTest::newRow("ReadOnly") << "ReadOnly" << static_cast<int>(QScriptValue::ReadOnly);
   1204     QTest::newRow("Undeletable") << "Undeletable" << static_cast<int>(QScriptValue::Undeletable);
   1205     QTest::newRow("SkipInEnumeration") << "SkipInEnumeration" << static_cast<int>(QScriptValue::SkipInEnumeration);
   1206     QTest::newRow("ReadOnly | Undeletable") << "ReadOnly_Undeletable" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable);
   1207     QTest::newRow("ReadOnly | SkipInEnumeration") << "ReadOnly_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
   1208     QTest::newRow("Undeletable | SkipInEnumeration") << "Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
   1209     QTest::newRow("ReadOnly | Undeletable | SkipInEnumeration") << "ReadOnly_Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
   1210 }
   1211 
   1212 void tst_QScriptValue::propertyFlag()
   1213 {
   1214     QScriptEngine engine;
   1215     QFETCH(QString, name);
   1216     QFETCH(int, flag);
   1217     const QScriptString nameHandle = engine.toStringHandle(name);
   1218     const QString protoName = "proto" + name;
   1219     const QScriptString protoNameHandle = engine.toStringHandle(protoName);
   1220 
   1221     QScriptValue proto = engine.newObject();
   1222     QScriptValue object = engine.newObject();
   1223     object.setPrototype(proto);
   1224 
   1225     proto.setProperty(protoName, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
   1226     object.setProperty(name, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
   1227 
   1228     // Check using QString name
   1229     QCOMPARE(object.propertyFlags(name), QScriptValue::PropertyFlag(flag));
   1230     QCOMPARE(object.propertyFlags(protoName, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
   1231     QVERIFY(!object.propertyFlags(protoName, QScriptValue::ResolveLocal));
   1232 
   1233     // Check using QScriptString name
   1234     QCOMPARE(object.propertyFlags(nameHandle), QScriptValue::PropertyFlag(flag));
   1235     QCOMPARE(object.propertyFlags(protoNameHandle, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
   1236     QVERIFY(!object.propertyFlags(protoNameHandle, QScriptValue::ResolveLocal));
   1237 }
   1238 
   1239 void tst_QScriptValue::globalObjectChanges()
   1240 {
   1241     // API functionality shouldn't depend on Global Object.
   1242     QScriptEngine engine;
   1243     QScriptValue array = engine.newArray();
   1244     QScriptValue error = engine.evaluate("new Error");
   1245     QScriptValue object = engine.newObject();
   1246 
   1247     object.setProperty("foo", 512);
   1248 
   1249     // Remove properties form global object.
   1250     engine.evaluate("delete Object; delete Error; delete Array;");
   1251 
   1252     QVERIFY(array.isArray());
   1253     QVERIFY(error.isError());
   1254     QVERIFY(object.isObject());
   1255 
   1256     QVERIFY(object.property("foo").isValid());
   1257     QVERIFY(object.property("foo", QScriptValue::ResolveLocal).isValid());
   1258     object.setProperty("foo", QScriptValue());
   1259     QVERIFY(!object.property("foo").isValid());
   1260     QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid());
   1261 }
   1262 
   1263 void tst_QScriptValue::assignAndCopyConstruct_data()
   1264 {
   1265     QTest::addColumn<QScriptValue>("value");
   1266     if (m_engine)
   1267         delete m_engine;
   1268     m_engine = new QScriptEngine;
   1269     // Copy & assign code is the same for all types, so it is enough to check only a few value.
   1270     for (unsigned i = 0; i < 10; ++i) {
   1271         QPair<QString, QScriptValue> testcase = initScriptValues(i);
   1272         QTest::newRow(testcase.first.toAscii().constData()) << testcase.second;
   1273     }
   1274 }
   1275 
   1276 void tst_QScriptValue::assignAndCopyConstruct()
   1277 {
   1278     QFETCH(QScriptValue, value);
   1279     QScriptValue copy(value);
   1280     QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Abort);
   1281     QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Abort);
   1282     QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber()));
   1283     QCOMPARE(copy.engine(), value.engine());
   1284 
   1285     QScriptValue assigned = copy;
   1286     QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber()));
   1287     QCOMPARE(assigned.engine(), assigned.engine());
   1288 
   1289     QScriptValue other(!value.toBool());
   1290     assigned = other;
   1291     QVERIFY(!assigned.strictlyEquals(copy));
   1292     QVERIFY(assigned.strictlyEquals(other));
   1293     QCOMPARE(assigned.engine(), other.engine());
   1294 }
   1295 
   1296 QTEST_MAIN(tst_QScriptValue)
   1297