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