Changeset 62547 in webkit
- Timestamp:
- Jul 6, 2010 6:55:34 AM (14 years ago)
- Location:
- trunk/JavaScriptCore/qt
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/qt/ChangeLog
r62382 r62547 1 2010-07-06 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 Implementation of QScriptValue properties accessors. 6 7 The patch contains implementation of the QScriptValue::property() and 8 the QScriptValue::setProperty(). It is not full functionality, as these 9 method are too complex for one patch, but it is enough to cover about 10 95% of use cases. 11 12 Missing functionality: 13 - Few of the PropertyFlags are ignored. 14 - Only a public part of the ResolveFlags can be used (ResolveLocal, 15 ResolvePrototype). 16 17 A lot of new test cases were added. 18 19 [Qt] QScriptValue should have API for accessing object properties 20 https://bugs.webkit.org/show_bug.cgi?id=40903 21 22 * api/qscriptconverter_p.h: 23 (QScriptConverter::toPropertyFlags): 24 * api/qscriptstring_p.h: 25 (QScriptStringPrivate::operator JSStringRef): 26 * api/qscriptvalue.cpp: 27 (QScriptValue::property): 28 (QScriptValue::setProperty): 29 * api/qscriptvalue.h: 30 (QScriptValue::): 31 * api/qscriptvalue_p.h: 32 (QScriptValuePrivate::assignEngine): 33 (QScriptValuePrivate::property): 34 (QScriptValuePrivate::hasOwnProperty): 35 (QScriptValuePrivate::setProperty): 36 (QScriptValuePrivate::deleteProperty): 37 * tests/qscriptvalue/tst_qscriptvalue.cpp: 38 (tst_QScriptValue::getPropertySimple_data): 39 (tst_QScriptValue::getPropertySimple): 40 (tst_QScriptValue::setPropertySimple): 41 (tst_QScriptValue::getPropertyResolveFlag): 42 (tst_QScriptValue::getSetProperty): 43 (tst_QScriptValue::setProperty_data): 44 (tst_QScriptValue::setProperty): 45 * tests/qscriptvalue/tst_qscriptvalue.h: 46 1 47 2010-07-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> 2 48 -
trunk/JavaScriptCore/qt/api/qscriptconverter_p.h
r55634 r62547 21 21 #define qscriptconverter_p_h 22 22 23 #include "qscriptvalue.h" 23 24 #include <JavaScriptCore/JavaScript.h> 25 #include <QtCore/qglobal.h> 24 26 #include <QtCore/qnumeric.h> 25 27 #include <QtCore/qstring.h> … … 128 130 return QString::fromLatin1(buf.constData()); 129 131 } 132 133 static JSPropertyAttributes toPropertyFlags(const QFlags<QScriptValue::PropertyFlag>& flags) 134 { 135 JSPropertyAttributes attr = 0; 136 if (flags.testFlag(QScriptValue::ReadOnly)) 137 attr |= kJSPropertyAttributeReadOnly; 138 if (flags.testFlag(QScriptValue::Undeletable)) 139 attr |= kJSPropertyAttributeDontDelete; 140 if (flags.testFlag(QScriptValue::SkipInEnumeration)) 141 attr |= kJSPropertyAttributeDontEnum; 142 return attr; 143 } 130 144 }; 131 145 -
trunk/JavaScriptCore/qt/api/qscriptstring_p.h
r58248 r62547 46 46 47 47 inline quint64 id() const; 48 49 inline operator JSStringRef() const; 48 50 49 51 private: … … 110 112 } 111 113 114 /*! 115 \internal 116 This method should be used for invoking JSC functions. 117 \note This method keeps ownership of an internal JSStringRef. 118 */ 119 QScriptStringPrivate::operator JSStringRef() const 120 { 121 return m_string; 122 } 123 112 124 #endif // qscriptstring_p_h -
trunk/JavaScriptCore/qt/api/qscriptvalue.cpp
r62007 r62547 652 652 \overload 653 653 654 Returns the value of this QScriptValue's property with the given \a name, 655 using the given \a mode to resolve the property. 656 657 This overload of property() is useful when you need to look up the 658 same property repeatedly, since the lookup can be performed faster 659 when the name is represented as an interned string. 660 661 \sa QScriptEngine::toStringHandle(), setProperty() 662 */ 663 QScriptValue QScriptValue::property(const QScriptString& name, const ResolveFlags& mode) const 664 { 665 return QScriptValuePrivate::get(d_ptr->property(QScriptStringPrivate::get(name).constData(), mode)); 666 } 667 668 /*! 669 \overload 670 654 671 Returns the property at the given \a arrayIndex, using the given \a 655 672 mode to resolve the property. … … 666 683 return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode)); 667 684 } 685 686 /*! 687 Sets the value of this QScriptValue's property with the given \a name to 688 the given \a value. 689 690 If this QScriptValue is not an object, this function does nothing. 691 692 If this QScriptValue does not already have a property with name \a name, 693 a new property is created; the given \a flags then specify how this 694 property may be accessed by script code. 695 696 If \a value is invalid, the property is removed. 697 698 If the property is implemented using a setter function (i.e. has the 699 PropertySetter flag set), calling setProperty() has side-effects on 700 the script engine, since the setter function will be called with the 701 given \a value as argument (possibly resulting in an uncaught script 702 exception). 703 704 Note that you cannot specify custom getter or setter functions for 705 built-in properties, such as the \c{length} property of Array objects 706 or meta properties of QObject objects. 707 708 \sa property() 709 */ 710 void QScriptValue::setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags) 711 { 712 d_ptr->setProperty(name, QScriptValuePrivate::get(value), flags); 713 } 714 715 /*! 716 \overload 717 718 Sets the property at the given \a arrayIndex to the given \a value. 719 720 This function is provided for convenience and performance when 721 working with array objects. 722 723 If this QScriptValue is not an Array object, this function behaves 724 as if setProperty() was called with the string representation of \a 725 arrayIndex. 726 */ 727 void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags) 728 { 729 d_ptr->setProperty(arrayIndex, QScriptValuePrivate::get(value), flags); 730 } 731 732 /*! 733 Sets the value of this QScriptValue's property with the given \a 734 name to the given \a value. The given \a flags specify how this 735 property may be accessed by script code. 736 737 This overload of setProperty() is useful when you need to set the 738 same property repeatedly, since the operation can be performed 739 faster when the name is represented as an interned string. 740 741 \sa QScriptEngine::toStringHandle() 742 */ 743 void QScriptValue::setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags) 744 { 745 d_ptr->setProperty(QScriptStringPrivate::get(name).constData(), QScriptValuePrivate::get(value), flags); 746 } -
trunk/JavaScriptCore/qt/api/qscriptvalue.h
r62007 r62547 21 21 #define qscriptvalue_h 22 22 23 #include "qscriptstring.h" 23 24 #include <QtCore/qlist.h> 24 25 #include <QtCore/qshareddata.h> … … 35 36 public: 36 37 enum ResolveFlag { 37 ResolveLocal = 0x00, 38 ResolvePrototype = 0x01 38 ResolveLocal = 0x00, 39 ResolvePrototype = 0x01, 40 ResolveScope = 0x02, 41 ResolveFull = ResolvePrototype | ResolveScope 39 42 }; 43 Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag) 40 44 41 Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag) 45 enum PropertyFlag { 46 ReadOnly = 0x00000001, 47 Undeletable = 0x00000002, 48 SkipInEnumeration = 0x00000004, 49 PropertyGetter = 0x00000008, 50 PropertySetter = 0x00000010, 51 QObjectMember = 0x00000020, 52 KeepExistingFlags = 0x00000800, 53 UserRange = 0xff000000 // Users may use these as they see fit. 54 }; 55 Q_DECLARE_FLAGS(PropertyFlags, PropertyFlag) 42 56 43 57 enum SpecialValue { … … 76 90 77 91 QScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const; 92 QScriptValue property(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) const; 78 93 QScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const; 94 95 void setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); 96 void setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); 97 void setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); 79 98 80 99 QScriptEngine* engine() const; … … 103 122 QScriptValue call(const QScriptValue& thisObject = QScriptValue(), 104 123 const QScriptValueList& args = QScriptValueList()); 105 106 124 private: 107 125 QScriptValue(void*); -
trunk/JavaScriptCore/qt/api/qscriptvalue_p.h
r62377 r62547 122 122 123 123 inline QScriptValuePrivate* property(const QString& name, const QScriptValue::ResolveFlags& mode); 124 inline QScriptValuePrivate* property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode); 124 125 inline QScriptValuePrivate* property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode); 126 inline JSValueRef property(quint32 property, JSValueRef* exception); 127 inline JSValueRef property(JSStringRef property, JSValueRef* exception); 128 inline bool hasOwnProperty(quint32 property); 129 inline bool hasOwnProperty(JSStringRef property); 130 template<typename T> 131 inline QScriptValuePrivate* property(T name, const QScriptValue::ResolveFlags& mode); 132 133 inline void setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); 134 inline void setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); 135 inline void setProperty(const quint32 indexArray, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); 136 inline void setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception); 137 inline void setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception); 138 inline void deleteProperty(quint32 property, JSValueRef* exception); 139 inline void deleteProperty(JSStringRef property, JSValueRef* exception); 140 template<typename T> 141 inline void setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); 125 142 126 143 inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args); … … 745 762 bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine) 746 763 { 764 Q_ASSERT(engine); 747 765 JSValueRef value; 748 766 switch (m_state) { … … 779 797 inline QScriptValuePrivate* QScriptValuePrivate::property(const QString& name, const QScriptValue::ResolveFlags& mode) 780 798 { 799 JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name)); 800 return property<JSStringRef>(propertyName.get(), mode); 801 } 802 803 inline QScriptValuePrivate* QScriptValuePrivate::property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode) 804 { 805 return property<JSStringRef>(*name, mode); 806 } 807 808 inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode) 809 { 810 return property<quint32>(arrayIndex, mode); 811 } 812 813 /*! 814 \internal 815 This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty. 816 */ 817 inline JSValueRef QScriptValuePrivate::property(quint32 property, JSValueRef* exception) 818 { 819 return JSObjectGetPropertyAtIndex(*m_engine, *this, property, exception); 820 } 821 822 /*! 823 \internal 824 This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty. 825 */ 826 inline JSValueRef QScriptValuePrivate::property(JSStringRef property, JSValueRef* exception) 827 { 828 return JSObjectGetProperty(*m_engine, *this, property, exception); 829 } 830 831 /*! 832 \internal 833 This method was created to unify acccess to hasOwnProperty, same function for an array index 834 and a property name access. 835 */ 836 inline bool QScriptValuePrivate::hasOwnProperty(quint32 property) 837 { 838 Q_ASSERT(isObject()); 839 // FIXME it could be faster, but JSC C API doesn't expose needed functionality. 840 JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); 841 return hasOwnProperty(propertyName.get()); 842 } 843 844 /*! 845 \internal 846 This method was created to unify acccess to hasOwnProperty, same function for an array index 847 and a property name access. 848 */ 849 inline bool QScriptValuePrivate::hasOwnProperty(JSStringRef property) 850 { 851 Q_ASSERT(isObject()); 852 // FIXME it could be faster, but JSC C API doesn't expose needed functionality. 853 JSRetainPtr<JSStringRef> hasOwnPropertyName(Adopt, JSStringCreateWithUTF8CString("hasOwnProperty")); 854 JSValueRef exception = 0; 855 JSValueRef hasOwnProperty = JSObjectGetProperty(*m_engine, *this, hasOwnPropertyName.get(), &exception); 856 JSValueRef propertyName[] = { JSValueMakeString(*m_engine, property) }; 857 JSValueRef result = JSObjectCallAsFunction(*m_engine, const_cast<JSObjectRef>(hasOwnProperty), *this, 1, propertyName, &exception); 858 return exception ? false : JSValueToBoolean(*m_engine, result); 859 } 860 861 /*! 862 \internal 863 This function gets property of an object. 864 \arg propertyName could be type of quint32 (an array index) or JSStringRef (a property name). 865 */ 866 template<typename T> 867 inline QScriptValuePrivate* QScriptValuePrivate::property(T propertyName, const QScriptValue::ResolveFlags& mode) 868 { 781 869 if (!isObject()) 870 return new QScriptValuePrivate(); 871 872 if ((mode == QScriptValue::ResolveLocal) && (!hasOwnProperty(propertyName))) 873 return new QScriptValuePrivate(); 874 875 JSValueRef exception = 0; 876 JSValueRef value = property(propertyName, &exception); 877 878 if (exception) { 879 m_engine->setException(exception, QScriptEnginePrivate::NotNullException); 880 return new QScriptValuePrivate(engine(), exception); 881 } 882 if (JSValueIsUndefined(*m_engine, value)) 782 883 return new QScriptValuePrivate; 783 784 if (mode & QScriptValue::ResolveLocal) { 785 qWarning("QScriptValue::property(): ResolveLocal not supported yet."); 786 return new QScriptValuePrivate; 787 } 788 789 JSRetainPtr<JSStringRef> nameRef(Adopt, QScriptConverter::toString(name)); 790 QScriptValuePrivate* result = new QScriptValuePrivate(m_engine.constData(), JSObjectGetProperty(*m_engine, *this, nameRef.get(), /* exception */ 0)); 791 792 return result; 793 } 794 795 inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode) 884 return new QScriptValuePrivate(engine(), value); 885 } 886 887 inline void QScriptValuePrivate::setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) 888 { 889 JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name)); 890 setProperty<JSStringRef>(propertyName.get(), value, flags); 891 } 892 893 inline void QScriptValuePrivate::setProperty(quint32 arrayIndex, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) 894 { 895 setProperty<quint32>(arrayIndex, value, flags); 896 } 897 898 inline void QScriptValuePrivate::setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) 899 { 900 setProperty<JSStringRef>(*name, value, flags); 901 } 902 903 /*! 904 \internal 905 This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty. 906 */ 907 inline void QScriptValuePrivate::setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception) 908 { 909 Q_ASSERT(isObject()); 910 if (flags) { 911 // FIXME This could be better, but JSC C API doesn't expose needed functionality. It is 912 // not possible to create / modify a property attribute via an array index. 913 JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); 914 JSObjectSetProperty(*m_engine, *this, propertyName.get(), value, flags, exception); 915 return; 916 } 917 JSObjectSetPropertyAtIndex(*m_engine, *this, property, value, exception); 918 } 919 920 /*! 921 \internal 922 This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty. 923 */ 924 inline void QScriptValuePrivate::setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception) 925 { 926 Q_ASSERT(isObject()); 927 JSObjectSetProperty(*m_engine, *this, property, value, flags, exception); 928 } 929 930 /*! 931 \internal 932 This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex 933 which doesn't exist now. 934 */ 935 inline void QScriptValuePrivate::deleteProperty(quint32 property, JSValueRef* exception) 936 { 937 // FIXME It could be faster, we need a JSC C API for deleting array index properties. 938 JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); 939 JSObjectDeleteProperty(*m_engine, *this, propertyName.get(), exception); 940 } 941 942 /*! 943 \internal 944 This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex. 945 */ 946 inline void QScriptValuePrivate::deleteProperty(JSStringRef property, JSValueRef* exception) 947 { 948 Q_ASSERT(isObject()); 949 JSObjectDeleteProperty(*m_engine, *this, property, exception); 950 } 951 952 template<typename T> 953 inline void QScriptValuePrivate::setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) 796 954 { 797 955 if (!isObject()) 798 return new QScriptValuePrivate; 799 800 if (mode & QScriptValue::ResolveLocal) { 801 qWarning("QScriptValue::property(): ResolveLocal not supported yet."); 802 return new QScriptValuePrivate; 803 } 804 805 return new QScriptValuePrivate(m_engine.constData(), JSObjectGetPropertyAtIndex(*m_engine, *this, arrayIndex, /* exception */ 0)); 806 } 956 return; 957 958 if (!value->isJSBased()) 959 value->assignEngine(engine()); 960 961 JSValueRef exception = 0; 962 if (!value->isValid()) { 963 // Remove the property. 964 deleteProperty(name, &exception); 965 m_engine->setException(exception); 966 return; 967 } 968 if (m_engine != value->m_engine) { 969 qWarning("QScriptValue::setProperty() failed: cannot set value created in a different engine"); 970 return; 971 } 972 973 setProperty(name, *value, QScriptConverter::toPropertyFlags(flags), &exception); 974 m_engine->setException(exception); 975 } 976 807 977 808 978 QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args) -
trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
r62007 r62547 273 273 QVERIFY(QScriptValue(0, "ciao").isString()); 274 274 QVERIFY(QScriptValue(0, QString("ciao")).isString()); 275 } 276 277 void tst_QScriptValue::getPropertySimple_data() 278 { 279 QTest::addColumn<QString>("code"); 280 QTest::addColumn<QString>("propertyName"); 281 QTest::addColumn<QString>("desc"); 282 QTest::addColumn<bool>("isArrayIndex"); 283 284 QTest::newRow("new Array()") 285 << QString::fromAscii("new Array()") 286 << QString::fromAscii("length") 287 << QString::fromAscii("0") 288 << false; 289 QTest::newRow("new Object().length") 290 << QString::fromAscii("new Object()") 291 << QString::fromAscii("length") 292 << QString::fromAscii("") // Undefined is an invalid property. 293 << false; 294 QTest::newRow("new Object().toString") 295 << QString::fromAscii("new Object()") 296 << QString::fromAscii("toString") 297 << QString::fromAscii("function toString() {\n [native code]\n}") 298 << false; 299 QTest::newRow("[1,2,3,4]") 300 << QString::fromAscii("[1,2,3,'s',4]") 301 << QString::fromAscii("2") 302 << QString::fromAscii("3") 303 << true; 304 QTest::newRow("[1,3,'a','b']") 305 << QString::fromAscii("[1,3,'a','b']") 306 << QString::fromAscii("3") 307 << QString::fromAscii("b") 308 << true; 309 QTest::newRow("[4,5]") 310 << QString::fromAscii("[4,5]") 311 << QString::fromAscii("123") 312 << QString::fromAscii("") // Undefined is an invalid property. 313 << true; 314 QTest::newRow("[1,3,4]") 315 << QString::fromAscii("[1,3,4]") 316 << QString::fromAscii("abc") 317 << QString::fromAscii("") // Undefined is an invalid property. 318 << true; 319 } 320 321 void tst_QScriptValue::getPropertySimple() 322 { 323 QFETCH(QString, code); 324 QFETCH(QString, propertyName); 325 QFETCH(QString, desc); 326 327 QScriptEngine engine; 328 QScriptValue object = engine.evaluate(code); 329 QVERIFY(object.isValid()); 330 { 331 QScriptValue property = object.property(propertyName); 332 QCOMPARE(property.toString(), desc); 333 } 334 { 335 QScriptString name = engine.toStringHandle(propertyName); 336 QScriptValue property = object.property(name); 337 QCOMPARE(property.toString(), desc); 338 } 339 { 340 bool ok; 341 quint32 idx = engine.toStringHandle(propertyName).toArrayIndex(&ok); 342 if (ok) { 343 QScriptValue property = object.property(idx); 344 QCOMPARE(property.toString(), desc); 345 } 346 } 347 } 348 349 void tst_QScriptValue::setPropertySimple() 350 { 351 QScriptEngine engine; 352 { 353 QScriptValue invalid; 354 QScriptValue property(1234); 355 356 invalid.setProperty("aaa", property); 357 invalid.setProperty(13, property); 358 invalid.setProperty(engine.toStringHandle("aaa"), property); 359 360 QVERIFY(!invalid.property("aaa").isValid()); 361 QVERIFY(!invalid.property(13).isValid()); 362 QVERIFY(!invalid.property(engine.toStringHandle("aaa")).isValid()); 363 } 364 { 365 QScriptValue object = engine.newObject(); 366 QScriptValue property; 367 368 object.setProperty(13, property); 369 object.setProperty("aaa", property); 370 object.setProperty(engine.toStringHandle("aaa"), property); 371 372 QVERIFY(!object.property(13).isValid()); 373 QVERIFY(!object.property("aaa").isValid()); 374 QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid()); 375 } 376 { 377 // Check if setting an invalid property works as deleteProperty. 378 QScriptValue object = engine.evaluate("o = {13: 0, 'aaa': 3, 'bbb': 1}"); 379 QScriptValue property; 380 381 QVERIFY(object.property(13).isValid()); 382 QVERIFY(object.property("aaa").isValid()); 383 QVERIFY(object.property(engine.toStringHandle("aaa")).isValid()); 384 385 object.setProperty(13, property); 386 object.setProperty("aaa", property); 387 object.setProperty(engine.toStringHandle("bbb"), property); 388 389 QVERIFY(!object.property(13).isValid()); 390 QVERIFY(!object.property("aaa").isValid()); 391 QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid()); 392 } 393 { 394 QScriptValue object = engine.evaluate("new Object"); 395 QVERIFY(object.isObject()); 396 QScriptValue property = object.property("foo"); 397 QVERIFY(!property.isValid()); 398 property = QScriptValue(2); 399 object.setProperty("foo", property); 400 QVERIFY(object.property("foo").isNumber()); 401 QVERIFY(object.property("foo").toNumber() == 2); 402 } 403 { 404 QScriptValue o1 = engine.evaluate("o1 = new Object; o1"); 405 QScriptValue o2 = engine.evaluate("o2 = new Object; o2"); 406 QVERIFY(engine.evaluate("o1.__proto__ = o2; o1.__proto__ === o2").toBool()); 407 QVERIFY(engine.evaluate("o2.foo = 22; o1.foo == 22").toBool()); 408 QVERIFY(o1.property("foo").toString() == "22"); 409 o2.setProperty("foo", QScriptValue(&engine, 456.0)); 410 QVERIFY(engine.evaluate("o1.foo == 456").toBool()); 411 QVERIFY(o1.property("foo").isNumber()); 412 } 413 } 414 415 void tst_QScriptValue::getPropertyResolveFlag() 416 { 417 QScriptEngine engine; 418 QScriptValue object1 = engine.evaluate("o1 = new Object();"); 419 QScriptValue object2 = engine.evaluate("o2 = new Object(); o1.__proto__ = o2; o2"); 420 QScriptValue number(&engine, 456.0); 421 QVERIFY(object1.isObject()); 422 QVERIFY(object2.isObject()); 423 QVERIFY(number.isNumber()); 424 425 object2.setProperty("propertyInPrototype", number); 426 QVERIFY(object2.property("propertyInPrototype").isNumber()); 427 // default is ResolvePrototype 428 QCOMPARE(object1.property("propertyInPrototype").strictlyEquals(number), true); 429 QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolvePrototype) 430 .strictlyEquals(number), true); 431 QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolveLocal).isValid(), false); 432 } 433 434 void tst_QScriptValue::getSetProperty() 435 { 436 QScriptEngine eng; 437 438 QScriptValue object = eng.newObject(); 439 440 QScriptValue str = QScriptValue(&eng, "bar"); 441 object.setProperty("foo", str); 442 QCOMPARE(object.property("foo").toString(), str.toString()); 443 444 QScriptValue num = QScriptValue(&eng, 123.0); 445 object.setProperty("baz", num); 446 QCOMPARE(object.property("baz").toNumber(), num.toNumber()); 447 448 QScriptValue strstr = QScriptValue("bar"); 449 QCOMPARE(strstr.engine(), (QScriptEngine *)0); 450 object.setProperty("foo", strstr); 451 QCOMPARE(object.property("foo").toString(), strstr.toString()); 452 QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine 453 454 QScriptValue numnum = QScriptValue(123.0); 455 object.setProperty("baz", numnum); 456 QCOMPARE(object.property("baz").toNumber(), numnum.toNumber()); 457 458 QScriptValue inv; 459 inv.setProperty("foo", num); 460 QCOMPARE(inv.property("foo").isValid(), false); 461 462 QScriptValue array = eng.newArray(); 463 array.setProperty(0, num); 464 QCOMPARE(array.property(0).toNumber(), num.toNumber()); 465 QCOMPARE(array.property("0").toNumber(), num.toNumber()); 466 QCOMPARE(array.property("length").toUInt32(), quint32(1)); 467 array.setProperty(1, str); 468 QCOMPARE(array.property(1).toString(), str.toString()); 469 QCOMPARE(array.property("1").toString(), str.toString()); 470 QCOMPARE(array.property("length").toUInt32(), quint32(2)); 471 array.setProperty("length", QScriptValue(&eng, 1)); 472 QCOMPARE(array.property("length").toUInt32(), quint32(1)); 473 QCOMPARE(array.property(1).isValid(), false); 474 475 // task 162051 -- detecting whether the property is an array index or not 476 QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123))); 477 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); 478 QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QScriptValue(&eng, true))); 479 QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QScriptValue(&eng, false))); 480 QVERIFY(eng.evaluate("a[0]").isUndefined()); 481 QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QScriptValue(&eng, 456))); 482 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); 483 QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QScriptValue(&eng, true))); 484 QVERIFY(eng.evaluate("a[0]").isUndefined()); 485 QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789))); 486 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1))); 487 488 // task 183072 -- 0x800000000 is not an array index 489 eng.evaluate("a = []; a[0x800000000] = 123"); 490 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); 491 QVERIFY(eng.evaluate("a[0]").isUndefined()); 492 QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123))); 493 494 QScriptEngine otherEngine; 495 QScriptValue otherNum = QScriptValue(&otherEngine, 123); 496 QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: cannot set value created in a different engine"); 497 object.setProperty("oof", otherNum); 498 QCOMPARE(object.property("oof").isValid(), false); 499 500 // test ResolveMode 501 QScriptValue object2 = eng.newObject(); 502 object.setPrototype(object2); 503 QScriptValue num2 = QScriptValue(&eng, 456.0); 504 object2.setProperty("propertyInPrototype", num2); 505 // default is ResolvePrototype 506 QCOMPARE(object.property("propertyInPrototype") 507 .strictlyEquals(num2), true); 508 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolvePrototype) 509 .strictlyEquals(num2), true); 510 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveLocal) 511 .isValid(), false); 512 QEXPECT_FAIL("", "QScriptValue::ResolveScope is not implemented", Continue); 513 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveScope) 514 .strictlyEquals(num2), false); 515 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull) 516 .strictlyEquals(num2), true); 517 518 // test property removal (setProperty(QScriptValue())) 519 QScriptValue object3 = eng.newObject(); 520 object3.setProperty("foo", num); 521 QCOMPARE(object3.property("foo").strictlyEquals(num), true); 522 object3.setProperty("bar", str); 523 QCOMPARE(object3.property("bar").strictlyEquals(str), true); 524 object3.setProperty("foo", QScriptValue()); 525 QCOMPARE(object3.property("foo").isValid(), false); 526 QCOMPARE(object3.property("bar").strictlyEquals(str), true); 527 object3.setProperty("foo", num); 528 QCOMPARE(object3.property("foo").strictlyEquals(num), true); 529 QCOMPARE(object3.property("bar").strictlyEquals(str), true); 530 object3.setProperty("bar", QScriptValue()); 531 QCOMPARE(object3.property("bar").isValid(), false); 532 QCOMPARE(object3.property("foo").strictlyEquals(num), true); 533 object3.setProperty("foo", QScriptValue()); 534 object3.setProperty("foo", QScriptValue()); 535 536 eng.globalObject().setProperty("object3", object3); 537 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") 538 .strictlyEquals(QScriptValue(&eng, false)), true); 539 object3.setProperty("foo", num); 540 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") 541 .strictlyEquals(QScriptValue(&eng, true)), true); 542 eng.globalObject().setProperty("object3", QScriptValue()); 543 QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')") 544 .strictlyEquals(QScriptValue(&eng, false)), true); 545 546 eng.globalObject().setProperty("object", object); 547 548 // ReadOnly 549 object.setProperty("readOnlyProperty", num, QScriptValue::ReadOnly); 550 // QCOMPARE(object.propertyFlags("readOnlyProperty"), QScriptValue::ReadOnly); 551 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true); 552 eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty"); 553 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true); 554 // Should still be part of enumeration. 555 { 556 QScriptValue ret = eng.evaluate( 557 "found = false;" 558 "for (var p in object) {" 559 " if (p == 'readOnlyProperty') {" 560 " found = true; break;" 561 " }" 562 "} found"); 563 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); 564 } 565 // should still be deletable 566 { 567 QScriptValue ret = eng.evaluate("delete object.readOnlyProperty"); 568 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); 569 QCOMPARE(object.property("readOnlyProperty").isValid(), false); 570 } 571 572 // Undeletable 573 object.setProperty("undeletableProperty", num, QScriptValue::Undeletable); 574 // QCOMPARE(object.propertyFlags("undeletableProperty"), QScriptValue::Undeletable); 575 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true); 576 { 577 QScriptValue ret = eng.evaluate("delete object.undeletableProperty"); 578 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), false); 579 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true); 580 } 581 // should still be writable 582 eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1"); 583 QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1); 584 // should still be part of enumeration 585 { 586 QScriptValue ret = eng.evaluate( 587 "found = false;" 588 "for (var p in object) {" 589 " if (p == 'undeletableProperty') {" 590 " found = true; break;" 591 " }" 592 "} found"); 593 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); 594 } 595 // should still be deletable from C++ 596 object.setProperty("undeletableProperty", QScriptValue()); 597 QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); 598 QVERIFY(!object.property("undeletableProperty").isValid()); 599 // QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); 600 // QCOMPARE(object.propertyFlags("undeletableProperty"), 0); 601 602 // SkipInEnumeration 603 object.setProperty("dontEnumProperty", num, QScriptValue::SkipInEnumeration); 604 // QCOMPARE(object.propertyFlags("dontEnumProperty"), QScriptValue::SkipInEnumeration); 605 QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true); 606 // should not be part of enumeration 607 { 608 QScriptValue ret = eng.evaluate( 609 "found = false;" 610 "for (var p in object) {" 611 " if (p == 'dontEnumProperty') {" 612 " found = true; break;" 613 " }" 614 "} found"); 615 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, false)), true); 616 } 617 // should still be writable 618 eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1"); 619 QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1); 620 // should still be deletable 621 { 622 QScriptValue ret = eng.evaluate("delete object.dontEnumProperty"); 623 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); 624 QCOMPARE(object.property("dontEnumProperty").isValid(), false); 625 } 626 627 // change flags 628 object.setProperty("flagProperty", str); 629 // QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QScriptValue::PropertyFlags>(0)); 630 631 object.setProperty("flagProperty", str, QScriptValue::ReadOnly); 632 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly); 633 634 // object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QScriptValue::SkipInEnumeration); 635 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); 636 637 object.setProperty("flagProperty", str, QScriptValue::KeepExistingFlags); 638 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); 639 640 object.setProperty("flagProperty", str, QScriptValue::UserRange); 641 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::UserRange); 642 643 // flags of property in the prototype 644 { 645 QScriptValue object2 = eng.newObject(); 646 object2.setPrototype(object); 647 // QCOMPARE(object2.propertyFlags("flagProperty", QScriptValue::ResolveLocal), 0); 648 // QCOMPARE(object2.propertyFlags("flagProperty"), QScriptValue::UserRange); 649 } 650 651 // using interned strings 652 QScriptString foo = eng.toStringHandle("foo"); 653 654 object.setProperty(foo, QScriptValue()); 655 QVERIFY(!object.property(foo).isValid()); 656 657 object.setProperty(foo, num); 658 QVERIFY(object.property(foo).strictlyEquals(num)); 659 QVERIFY(object.property("foo").strictlyEquals(num)); 660 // QVERIFY(object.propertyFlags(foo) == 0); 275 661 } 276 662 … … 581 967 } 582 968 583 void tst_QScriptValue::propertySimple() 584 { 585 QScriptEngine eng; 586 587 QScriptValue simpleObject(eng.evaluate("new Object({ test: 1, other: 2 })")); 588 QCOMPARE(simpleObject.property("test").toUInt32(), quint32(1)); 589 QCOMPARE(simpleObject.property("other").toUInt32(), quint32(2)); 590 591 QScriptValue simpleArray(eng.evaluate("new Array(7, 8, 9)")); 592 QCOMPARE(simpleArray.property("length").toUInt32(), quint32(3)); 593 QCOMPARE(simpleArray.property(2).toUInt32(), quint32(9)); 969 void tst_QScriptValue::setProperty_data() 970 { 971 QTest::addColumn<QScriptValue>("property"); 972 QTest::addColumn<int>("flag"); 973 974 QTest::newRow("int + keepExistingFlags") << QScriptValue(123456) << static_cast<int>(QScriptValue::KeepExistingFlags); 975 QTest::newRow("int + undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::Undeletable); 976 QTest::newRow("int + readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly); 977 QTest::newRow("int + readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable); 978 QTest::newRow("int + skipInEnumeration") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration); 979 QTest::newRow("int + skipInEnumeration|readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly); 980 QTest::newRow("int + skipInEnumeration|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); 981 QTest::newRow("int + skipInEnumeration|readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly | QScriptValue::Undeletable); 982 } 983 984 void tst_QScriptValue::setProperty() 985 { 986 QFETCH(QScriptValue, property); 987 QFETCH(int, flag); 988 QScriptValue::PropertyFlags flags = static_cast<QScriptValue::PropertyFlag>(flag); 989 990 QScriptEngine engine; 991 QScriptValue object = engine.evaluate("o = new Object; o"); 992 QScriptValue proto = engine.evaluate("p = new Object; o.__proto__ = p; p"); 993 engine.evaluate("o.defined1 = 1"); 994 engine.evaluate("o.defined2 = 1"); 995 engine.evaluate("o[5] = 1"); 996 engine.evaluate("p.overloaded1 = 1"); 997 engine.evaluate("o.overloaded1 = 2"); 998 engine.evaluate("p[6] = 1"); 999 engine.evaluate("o[6] = 2"); 1000 engine.evaluate("p.overloaded2 = 1"); 1001 engine.evaluate("o.overloaded2 = 2"); 1002 engine.evaluate("p.overloaded3 = 1"); 1003 engine.evaluate("o.overloaded3 = 2"); 1004 engine.evaluate("p[7] = 1"); 1005 engine.evaluate("o[7] = 2"); 1006 engine.evaluate("p.overloaded4 = 1"); 1007 engine.evaluate("o.overloaded4 = 2"); 1008 1009 // tries to set undefined property directly on object. 1010 object.setProperty(QString::fromAscii("undefined1"), property, flags); 1011 QVERIFY(engine.evaluate("o.undefined1").strictlyEquals(property)); 1012 object.setProperty(engine.toStringHandle("undefined2"), property, flags); 1013 QVERIFY(object.property("undefined2").strictlyEquals(property)); 1014 object.setProperty(4, property, flags); 1015 QVERIFY(object.property(4).strictlyEquals(property)); 1016 1017 // tries to set defined property directly on object 1018 object.setProperty("defined1", property, flags); 1019 QVERIFY(engine.evaluate("o.defined1").strictlyEquals(property)); 1020 object.setProperty(engine.toStringHandle("defined2"), property, flags); 1021 QVERIFY(object.property("defined2").strictlyEquals(property)); 1022 object.setProperty(5, property, flags); 1023 QVERIFY(object.property(5).strictlyEquals(property)); 1024 1025 // tries to set overloaded property directly on object 1026 object.setProperty("overloaded1", property, flags); 1027 QVERIFY(engine.evaluate("o.overloaded1").strictlyEquals(property)); 1028 object.setProperty(engine.toStringHandle("overloaded2"), property, flags); 1029 QVERIFY(object.property("overloaded2").strictlyEquals(property)); 1030 object.setProperty(6, property, flags); 1031 QVERIFY(object.property(6).strictlyEquals(property)); 1032 1033 // tries to set overloaded property directly on prototype 1034 proto.setProperty("overloaded3", property, flags); 1035 QVERIFY(!engine.evaluate("o.overloaded3").strictlyEquals(property)); 1036 proto.setProperty(engine.toStringHandle("overloaded4"), property, flags); 1037 QVERIFY(!object.property("overloaded4").strictlyEquals(property)); 1038 proto.setProperty(7, property, flags); 1039 QVERIFY(!object.property(7).strictlyEquals(property)); 1040 1041 // tries to set undefined property directly on prototype 1042 proto.setProperty("undefined3", property, flags); 1043 QVERIFY(engine.evaluate("o.undefined3").strictlyEquals(property)); 1044 proto.setProperty(engine.toStringHandle("undefined4"), property, flags); 1045 QVERIFY(object.property("undefined4").strictlyEquals(property)); 1046 proto.setProperty(8, property, flags); 1047 QVERIFY(object.property(8).strictlyEquals(property)); 1048 1049 bool readOnly = flags & QScriptValue::ReadOnly; 1050 bool skipInEnumeration = flags & QScriptValue::SkipInEnumeration; 1051 bool undeletable = flags & QScriptValue::Undeletable; 1052 1053 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').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, '5').writable").toBool()); 1059 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1060 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1061 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1062 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1063 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').writable").toBool()); 1064 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1065 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1066 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1067 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1068 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').writable").toBool()); 1069 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').writable").toBool()); 1070 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').writable").toBool()); 1071 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').writable").toBool()); 1072 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').writable").toBool()); 1073 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').writable").toBool()); 1074 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1075 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1076 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1077 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1078 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').writable").toBool()); 1079 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1080 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1081 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1082 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1083 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').writable").toBool()); 1084 QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool()); 1085 QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool()); 1086 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1087 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1088 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1089 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1090 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').writable").toBool()); 1091 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1092 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1093 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1094 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1095 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').writable").toBool()); 1096 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1097 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1098 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1099 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1100 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').writable").toBool()); 1101 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1102 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1103 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1104 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1105 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').writable").toBool()); 1106 QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded3').writable").toBool()); 1107 QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded4').writable").toBool()); 1108 1109 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').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, '5').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, '6').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(p, '7').configurable").toBool()); 1125 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').configurable").toBool()); 1126 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').configurable").toBool()); 1127 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').configurable").toBool()); 1128 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').configurable").toBool()); 1129 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').configurable").toBool()); 1130 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1131 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1132 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1133 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1134 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').configurable").toBool()); 1135 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1136 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1137 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1138 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1139 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').configurable").toBool()); 1140 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1141 QEXPECT_FAIL("int + readOnly|undeletable", "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|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1144 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').configurable").toBool()); 1145 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1146 QEXPECT_FAIL("int + readOnly|undeletable", "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|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1149 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').configurable").toBool()); 1150 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded1').configurable").toBool()); 1151 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded2').configurable").toBool()); 1152 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded3').configurable").toBool()); 1153 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded4').configurable").toBool()); 1154 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1155 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1156 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1157 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1158 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').configurable").toBool()); 1159 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1160 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1161 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1162 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1163 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').configurable").toBool()); 1164 1165 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '4').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, '5').enumerable").toBool()); 1171 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1172 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1173 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1174 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1175 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '6').enumerable").toBool()); 1176 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1177 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1178 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1179 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1180 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '7').enumerable").toBool()); 1181 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '8').enumerable").toBool()); 1182 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined1').enumerable").toBool()); 1183 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined2').enumerable").toBool()); 1184 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined3').enumerable").toBool()); 1185 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined4').enumerable").toBool()); 1186 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1187 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1188 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1189 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1190 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded1').enumerable").toBool()); 1191 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1192 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1193 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1194 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1195 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded2').enumerable").toBool()); 1196 QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded1')").toBool()); 1197 QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded2')").toBool()); 1198 QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded3')").toBool()); 1199 QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded4')").toBool()); 1200 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1201 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1202 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1203 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1204 QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded3')").toBool()); 1205 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1206 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1207 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1208 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1209 QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded4')").toBool()); 1210 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1211 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1212 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1213 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1214 QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined1')").toBool()); 1215 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1216 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1217 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1218 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); 1219 QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined2')").toBool()); 594 1220 } 595 1221 -
trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
r62007 r62547 52 52 void ctor(); 53 53 void toObjectSimple(); 54 void propertySimple(); 54 void getPropertySimple_data(); 55 void getPropertySimple(); 56 void setPropertySimple(); 57 void setProperty_data(); 58 void setProperty(); 59 void getSetProperty(); 60 void getPropertyResolveFlag(); 55 61 56 62 // Generated test functions.
Note: See TracChangeset
for help on using the changeset viewer.