void tst_QScriptContext::getSetActivationObject() { QScriptEngine eng; QScriptContext *ctx = eng.currentContext(); QVERIFY(ctx->activationObject().equals(eng.globalObject())); ctx->setActivationObject(QScriptValue()); QVERIFY(ctx->activationObject().equals(eng.globalObject())); QCOMPARE(ctx->engine(), &eng); QScriptValue obj = eng.newObject(); ctx->setActivationObject(obj); QVERIFY(ctx->activationObject().equals(obj)); QCOMPARE(ctx->scopeChain().size(), 1); QVERIFY(ctx->scopeChain().at(0).equals(obj)); { QScriptEngine eng2; QScriptValue obj2 = eng2.newObject(); QTest::ignoreMessage(QtWarningMsg, "QScriptContext::setActivationObject() failed: cannot set an object created in a different engine"); QScriptValue was = ctx->activationObject(); ctx->setActivationObject(obj2); QVERIFY(ctx->activationObject().equals(was)); } ctx->setActivationObject(eng.globalObject()); QVERIFY(ctx->activationObject().equals(eng.globalObject())); QScriptValue fun = eng.newFunction(get_activationObject); eng.globalObject().setProperty("get_activationObject", fun); { QScriptValue ret = eng.evaluate("get_activationObject(1, 2, 3)"); QVERIFY(ret.isObject()); QScriptValue arguments = ret.property("arguments"); QEXPECT_FAIL("", "Getting arguments property of activation object doesn't work", Abort); QVERIFY(arguments.isObject()); QCOMPARE(arguments.property("length").toInt32(), 3); QCOMPARE(arguments.property("0").toInt32(), 1); QCOMPARE(arguments.property("1").toInt32(), 1); QCOMPARE(arguments.property("2").toInt32(), 1); } }
void tst_QScriptContext::pushAndPopContext() { QScriptEngine eng; QScriptContext *topLevel = eng.currentContext(); QCOMPARE(topLevel->engine(), &eng); QScriptContext *ctx = eng.pushContext(); QVERIFY(ctx != 0); QCOMPARE(ctx->parentContext(), topLevel); QCOMPARE(eng.currentContext(), ctx); QCOMPARE(ctx->engine(), &eng); QCOMPARE(ctx->state(), QScriptContext::NormalState); QCOMPARE(ctx->isCalledAsConstructor(), false); QCOMPARE(ctx->argumentCount(), 0); QCOMPARE(ctx->argument(0).isUndefined(), true); QVERIFY(!ctx->argument(-1).isValid()); QCOMPARE(ctx->argumentsObject().isObject(), true); QCOMPARE(ctx->activationObject().isObject(), true); QCOMPARE(ctx->callee().isValid(), false); QCOMPARE(ctx->thisObject().strictlyEquals(eng.globalObject()), true); QCOMPARE(ctx->scopeChain().size(), 2); QVERIFY(ctx->scopeChain().at(0).equals(ctx->activationObject())); QVERIFY(ctx->scopeChain().at(1).equals(eng.globalObject())); QScriptContext *ctx2 = eng.pushContext(); QCOMPARE(ctx2->parentContext(), ctx); QCOMPARE(eng.currentContext(), ctx2); eng.popContext(); QCOMPARE(eng.currentContext(), ctx); eng.popContext(); QCOMPARE(eng.currentContext(), topLevel); // popping the top-level context is not allowed QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::popContext() doesn't match with pushContext()"); eng.popContext(); QCOMPARE(eng.currentContext(), topLevel); { QScriptContext *ctx3 = eng.pushContext(); ctx3->activationObject().setProperty("foo", QScriptValue(&eng, 123)); QVERIFY(eng.evaluate("foo").strictlyEquals(QScriptValue(&eng, 123))); eng.evaluate("var bar = 'ciao'"); QVERIFY(ctx3->activationObject().property("bar", QScriptValue::ResolveLocal).strictlyEquals(QScriptValue(&eng, "ciao"))); eng.popContext(); } { QScriptContext *ctx4 = eng.pushContext(); QScriptValue obj = eng.newObject(); obj.setProperty("prop", QScriptValue(&eng, 456)); ctx4->setThisObject(obj); QScriptValue ret = eng.evaluate("var tmp = this.prop; tmp + 1"); QCOMPARE(eng.currentContext(), ctx4); QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 457))); eng.popContext(); } // throwing an exception { QScriptContext *ctx5 = eng.pushContext(); QScriptValue ret = eng.evaluate("throw new Error('oops')"); QVERIFY(ret.isError()); QVERIFY(eng.hasUncaughtException()); QCOMPARE(eng.currentContext(), ctx5); eng.popContext(); } }