void tst_QScriptClass::getAndSetProperty() { QScriptEngine eng; TestClass cls(&eng); QScriptValue obj1 = eng.newObject(&cls); QScriptValue obj2 = eng.newObject(&cls); QScriptString foo = eng.toStringHandle("foo"); QScriptString bar = eng.toStringHandle("bar"); // should behave just like normal for (int x = 0; x < 2; ++x) { QScriptValue &o = (x == 0) ? obj1 : obj2; for (int y = 0; y < 2; ++y) { QScriptString &s = (y == 0) ? foo : bar; // read property cls.clearReceivedArgs(); QScriptValue ret = o.property(s); QVERIFY(!ret.isValid()); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(o)); QVERIFY(cls.lastQueryPropertyName() == s); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(!cls.lastSetPropertyObject().isValid()); QVERIFY(cls.lastQueryPropertyFlags() == QScriptClass::HandlesReadAccess); // write property cls.clearReceivedArgs(); QScriptValue num(&eng, 123); o.setProperty(s, num); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(o)); QVERIFY(cls.lastQueryPropertyName() == s); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(!cls.lastSetPropertyObject().isValid()); // ### ideally, we should only test for HandlesWriteAccess in this case QVERIFY(cls.lastQueryPropertyFlags() == (QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess)); // re-read property cls.clearReceivedArgs(); QVERIFY(o.property(s).strictlyEquals(num)); QVERIFY(!cls.lastQueryPropertyObject().isValid()); } } // add a custom property QScriptString foo2 = eng.toStringHandle("foo2"); const uint foo2Id = 123; const QScriptValue::PropertyFlags foo2Pflags = QScriptValue::Undeletable; QScriptValue foo2Value(&eng, 456); cls.addCustomProperty(foo2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, foo2Id, foo2Pflags, foo2Value); { // read property cls.clearReceivedArgs(); { QScriptValue ret = obj1.property(foo2); QVERIFY(ret.strictlyEquals(foo2Value)); } QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QVERIFY(cls.lastPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyName() == foo2); QCOMPARE(cls.lastPropertyId(), foo2Id); // read flags cls.clearReceivedArgs(); QCOMPARE(obj1.propertyFlags(foo2), foo2Pflags); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(cls.lastPropertyFlagsObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyFlagsName() == foo2); QCOMPARE(cls.lastPropertyFlagsId(), foo2Id); // write property cls.clearReceivedArgs(); QScriptValue newFoo2Value(&eng, 789); obj1.setProperty(foo2, newFoo2Value); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); // read property again cls.clearReceivedArgs(); { QScriptValue ret = obj1.property(foo2); QVERIFY(ret.strictlyEquals(newFoo2Value)); } QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QVERIFY(cls.lastPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyName() == foo2); QCOMPARE(cls.lastPropertyId(), foo2Id); } }
void tst_QScriptClass::getAndSetProperty() { QScriptEngine eng; TestClass cls(&eng); QScriptValue obj1 = eng.newObject(&cls); QScriptValue obj2 = eng.newObject(&cls); QScriptString foo = eng.toStringHandle("foo"); QScriptString bar = eng.toStringHandle("bar"); QScriptValue num(&eng, 123); // should behave just like normal for (int x = 0; x < 2; ++x) { QScriptValue &o = (x == 0) ? obj1 : obj2; for (int y = 0; y < 2; ++y) { QScriptString &s = (y == 0) ? foo : bar; // read property cls.clearReceivedArgs(); QScriptValue ret = o.property(s); QVERIFY(!ret.isValid()); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(o)); QVERIFY(cls.lastQueryPropertyName() == s); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(!cls.lastSetPropertyObject().isValid()); QVERIFY(cls.lastQueryPropertyFlags() == QScriptClass::HandlesReadAccess); // write property cls.clearReceivedArgs(); o.setProperty(s, num); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(o)); QVERIFY(cls.lastQueryPropertyName() == s); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(!cls.lastSetPropertyObject().isValid()); QVERIFY(cls.lastQueryPropertyFlags() == QScriptClass::HandlesWriteAccess); // re-read property // When a QScriptClass doesn't want to handle a property write, // that property becomes a normal property and the QScriptClass // shall not be queried about it again. cls.clearReceivedArgs(); QVERIFY(o.property(s).strictlyEquals(num)); QVERIFY(!cls.lastQueryPropertyObject().isValid()); } } // add a custom property QScriptString foo2 = eng.toStringHandle("foo2"); const uint foo2Id = 123; const QScriptValue::PropertyFlags foo2Pflags = QScriptValue::Undeletable; QScriptValue foo2Value(&eng, 456); cls.addCustomProperty(foo2, QScriptClass::HandlesReadAccess | QScriptClass::HandlesWriteAccess, foo2Id, foo2Pflags, foo2Value); { // read property cls.clearReceivedArgs(); { QScriptValue ret = obj1.property(foo2); QVERIFY(ret.strictlyEquals(foo2Value)); } QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QVERIFY(cls.lastPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyName() == foo2); QCOMPARE(cls.lastPropertyId(), foo2Id); // read flags cls.clearReceivedArgs(); QCOMPARE(obj1.propertyFlags(foo2), foo2Pflags); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QEXPECT_FAIL("", "classObject.getOwnPropertyDescriptor() reads the property value", Continue); QVERIFY(!cls.lastPropertyObject().isValid()); QVERIFY(cls.lastPropertyFlagsObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyFlagsName() == foo2); QCOMPARE(cls.lastPropertyFlagsId(), foo2Id); // write property cls.clearReceivedArgs(); QScriptValue newFoo2Value(&eng, 789); obj1.setProperty(foo2, newFoo2Value); QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); // read property again cls.clearReceivedArgs(); { QScriptValue ret = obj1.property(foo2); QVERIFY(ret.strictlyEquals(newFoo2Value)); } QVERIFY(cls.lastQueryPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastQueryPropertyName() == foo2); QVERIFY(cls.lastPropertyObject().strictlyEquals(obj1)); QVERIFY(cls.lastPropertyName() == foo2); QCOMPARE(cls.lastPropertyId(), foo2Id); } // remove script class; normal properties should remain obj1.setScriptClass(0); QCOMPARE(obj1.scriptClass(), (QScriptClass*)0); QVERIFY(obj1.property(foo).equals(num)); QVERIFY(obj1.property(bar).equals(num)); obj1.setProperty(foo, QScriptValue()); QVERIFY(!obj1.property(foo).isValid()); obj1.setProperty(bar, QScriptValue()); QVERIFY(!obj1.property(bar).isValid()); }