tests/auto/qscriptengine/tst_qscriptengine.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
--- a/tests/auto/qscriptengine/tst_qscriptengine.cpp	Mon Jun 21 22:38:13 2010 +0100
+++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp	Thu Jul 22 16:41:55 2010 +0100
@@ -123,6 +123,7 @@
     void castWithPrototypeChain();
     void castWithMultipleInheritance();
     void collectGarbage();
+    void reportAdditionalMemoryCost();
     void gcWithNestedDataStructure();
     void processEventsWhileRunning();
     void throwErrorFromProcessEvents();
@@ -157,13 +158,17 @@
     void translateScript();
     void translateWithInvalidArgs_data();
     void translateWithInvalidArgs();
+    void translationContext_data();
+    void translationContext();
     void functionScopes();
     void nativeFunctionScopes();
     void evaluateProgram();
     void collectGarbageAfterConnect();
+    void promoteThisObjectToQObjectInConstructor();
 
     void qRegExpInport_data();
     void qRegExpInport();
+    void reentrency();
 };
 
 tst_QScriptEngine::tst_QScriptEngine()
@@ -798,6 +803,12 @@
     return obj;
 }
 
+static QScriptValue instanceofJS(const QScriptValue &inst, const QScriptValue &ctor)
+{
+    return inst.engine()->evaluate("(function(inst, ctor) { return inst instanceof ctor; })")
+        .call(QScriptValue(), QScriptValueList() << inst << ctor);
+}
+
 void tst_QScriptEngine::newQMetaObject()
 {
     QScriptEngine eng;
@@ -828,11 +839,15 @@
     QCOMPARE(instance.isQObject(), true);
     QCOMPARE(instance.toQObject()->metaObject(), qclass.toQMetaObject());
     QVERIFY(instance.instanceOf(qclass));
+    QVERIFY(instanceofJS(instance, qclass).strictlyEquals(true));
 
     QScriptValue instance2 = qclass2.construct();
     QCOMPARE(instance2.isQObject(), true);
     QCOMPARE(instance2.toQObject()->metaObject(), qclass2.toQMetaObject());
     QVERIFY(instance2.instanceOf(qclass2));
+    QVERIFY(instanceofJS(instance2, qclass2).strictlyEquals(true));
+    QVERIFY(!instance2.instanceOf(qclass));
+    QVERIFY(instanceofJS(instance2, qclass).strictlyEquals(false));
 
     QScriptValueList args;
     args << instance;
@@ -840,6 +855,9 @@
     QCOMPARE(instance3.isQObject(), true);
     QCOMPARE(instance3.toQObject()->parent(), instance.toQObject());
     QVERIFY(instance3.instanceOf(qclass));
+    QVERIFY(instanceofJS(instance3, qclass).strictlyEquals(true));
+    QVERIFY(!instance3.instanceOf(qclass2));
+    QVERIFY(instanceofJS(instance3, qclass2).strictlyEquals(false));
     args.clear();
 
     QPointer<QObject> qpointer1 = instance.toQObject();
@@ -875,6 +893,9 @@
         QVERIFY(ret.property("isCalledAsConstructor").isBoolean());
         QVERIFY(!ret.property("isCalledAsConstructor").toBoolean());
         QVERIFY(ret.instanceOf(qclass3));
+        QVERIFY(instanceofJS(ret, qclass3).strictlyEquals(true));
+        QVERIFY(!ret.instanceOf(qclass));
+        QVERIFY(instanceofJS(ret, qclass).strictlyEquals(false));
     }
     {
         QScriptValue ret = qclass3.construct();
@@ -882,11 +903,15 @@
         QVERIFY(ret.property("isCalledAsConstructor").isBoolean());
         QVERIFY(ret.property("isCalledAsConstructor").toBoolean());
         QVERIFY(ret.instanceOf(qclass3));
+        QVERIFY(instanceofJS(ret, qclass3).strictlyEquals(true));
+        QVERIFY(!ret.instanceOf(qclass2));
+        QVERIFY(instanceofJS(ret, qclass2).strictlyEquals(false));
     }
 
     // subclassing
     qclass2.setProperty("prototype", qclass.construct());
     QVERIFY(qclass2.construct().instanceOf(qclass));
+    QVERIFY(instanceofJS(qclass2.construct(), qclass).strictlyEquals(true));
 
     // with meta-constructor
     QScriptValue qclass4 = eng.newQMetaObject(&QObject::staticMetaObject);
@@ -896,6 +921,9 @@
         QVERIFY(inst.toQObject() != 0);
         QCOMPARE(inst.toQObject()->parent(), (QObject*)0);
         QVERIFY(inst.instanceOf(qclass4));
+        QVERIFY(instanceofJS(inst, qclass4).strictlyEquals(true));
+        QVERIFY(!inst.instanceOf(qclass3));
+        QVERIFY(instanceofJS(inst, qclass3).strictlyEquals(false));
     }
     {
         QScriptValue inst = qclass4.construct(QScriptValueList() << eng.newQObject(this));
@@ -903,6 +931,9 @@
         QVERIFY(inst.toQObject() != 0);
         QCOMPARE(inst.toQObject()->parent(), (QObject*)this);
         QVERIFY(inst.instanceOf(qclass4));
+        QVERIFY(instanceofJS(inst, qclass4).strictlyEquals(true));
+        QVERIFY(!inst.instanceOf(qclass2));
+        QVERIFY(instanceofJS(inst, qclass2).strictlyEquals(false));
     }
 }
 
@@ -2498,6 +2529,24 @@
     QVERIFY(ptr == 0);
 }
 
+void tst_QScriptEngine::reportAdditionalMemoryCost()
+{
+    QScriptEngine eng;
+    for (int x = 0; x < 1000; ++x) {
+        eng.reportAdditionalMemoryCost(0);
+        eng.reportAdditionalMemoryCost(10);
+        eng.reportAdditionalMemoryCost(1000);
+        eng.reportAdditionalMemoryCost(10000);
+        eng.reportAdditionalMemoryCost(100000);
+        eng.reportAdditionalMemoryCost(1000000);
+        eng.reportAdditionalMemoryCost(10000000);
+        eng.reportAdditionalMemoryCost(-1);
+        eng.reportAdditionalMemoryCost(-1000);
+        QScriptValue obj = eng.newObject();
+        eng.collectGarbage();
+    }
+}
+
 void tst_QScriptEngine::gcWithNestedDataStructure()
 {
     QScriptEngine eng;
@@ -3833,6 +3882,7 @@
         QVERIFY(tmp.isObject());
         QCOMPARE(tmp.toNumber(), falskt.toNumber());
     }
+    QVERIFY(falskt.isBool());
 
     QScriptValue sant(true);
     {
@@ -3840,6 +3890,7 @@
         QVERIFY(tmp.isObject());
         QCOMPARE(tmp.toNumber(), sant.toNumber());
     }
+    QVERIFY(sant.isBool());
 
     QScriptValue number(123.0);
     {
@@ -3847,6 +3898,7 @@
         QVERIFY(tmp.isObject());
         QCOMPARE(tmp.toNumber(), number.toNumber());
     }
+    QVERIFY(number.isNumber());
 
     QScriptValue str = QScriptValue(&eng, QString("ciao"));
     {
@@ -3854,6 +3906,7 @@
         QVERIFY(tmp.isObject());
         QCOMPARE(tmp.toString(), str.toString());
     }
+    QVERIFY(str.isString());
 
     QScriptValue object = eng.newObject();
     {
@@ -3866,6 +3919,32 @@
     QVERIFY(eng.toObject(qobject).strictlyEquals(qobject));
 
     QVERIFY(!eng.toObject(QScriptValue()).isValid());
+
+    // v1 constructors
+
+    QScriptValue boolValue(&eng, true);
+    {
+        QScriptValue ret = eng.toObject(boolValue);
+        QVERIFY(ret.isObject());
+        QCOMPARE(ret.toBool(), boolValue.toBool());
+    }
+    QVERIFY(boolValue.isBool());
+
+    QScriptValue numberValue(&eng, 123.0);
+    {
+        QScriptValue ret = eng.toObject(numberValue);
+        QVERIFY(ret.isObject());
+        QCOMPARE(ret.toNumber(), numberValue.toNumber());
+    }
+    QVERIFY(numberValue.isNumber());
+
+    QScriptValue stringValue(&eng, QString::fromLatin1("foo"));
+    {
+        QScriptValue ret = eng.toObject(stringValue);
+        QVERIFY(ret.isObject());
+        QCOMPARE(ret.toString(), stringValue.toString());
+    }
+    QVERIFY(stringValue.isString());
 }
 
 void tst_QScriptEngine::reservedWords_data()
@@ -4438,6 +4517,54 @@
     QCOMPARE(result.toString(), expectedError);
 }
 
+void tst_QScriptEngine::translationContext_data()
+{
+    QTest::addColumn<QString>("path");
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QString>("expectedTranslation");
+
+    QTest::newRow("translatable.js")  << "translatable.js" << "One" << "En";
+    QTest::newRow("/translatable.js")  << "/translatable.js" << "One" << "En";
+    QTest::newRow("/foo/translatable.js")  << "/foo/translatable.js" << "One" << "En";
+    QTest::newRow("/foo/bar/translatable.js")  << "/foo/bar/translatable.js" << "One" << "En";
+    QTest::newRow("./translatable.js")  << "./translatable.js" << "One" << "En";
+    QTest::newRow("../translatable.js")  << "../translatable.js" << "One" << "En";
+    QTest::newRow("foo/translatable.js")  << "foo/translatable.js" << "One" << "En";
+    QTest::newRow("file:///home/qt/translatable.js")  << "file:///home/qt/translatable.js" << "One" << "En";
+    QTest::newRow(":/resources/translatable.js")  << ":/resources/translatable.js" << "One" << "En";
+    QTest::newRow("/translatable.js.foo")  << "/translatable.js.foo" << "One" << "En";
+    QTest::newRow("/translatable.txt")  << "/translatable.txt" << "One" << "En";
+    QTest::newRow("translatable")  << "translatable" << "One" << "En";
+    QTest::newRow("foo/translatable")  << "foo/translatable" << "One" << "En";
+
+    QTest::newRow("native separators")
+        << (QDir::toNativeSeparators(QDir::currentPath()) + QDir::separator() + "translatable.js")
+        << "One" << "En";
+
+    QTest::newRow("translatable.js/")  << "translatable.js/" << "One" << "One";
+    QTest::newRow("nosuchscript.js")  << "" << "One" << "One";
+    QTest::newRow("(empty)")  << "" << "One" << "One";
+}
+
+void tst_QScriptEngine::translationContext()
+{
+    QTranslator translator;
+    translator.load(":/translations/translatable_la");
+    QCoreApplication::instance()->installTranslator(&translator);
+
+    QScriptEngine engine;
+    engine.installTranslatorFunctions();
+
+    QFETCH(QString, path);
+    QFETCH(QString, text);
+    QFETCH(QString, expectedTranslation);
+    QScriptValue ret = engine.evaluate(QString::fromLatin1("qsTr('%0')").arg(text), path);
+    QVERIFY(ret.isString());
+    QCOMPARE(ret.toString(), expectedTranslation);
+
+    QCoreApplication::instance()->removeTranslator(&translator);
+}
+
 void tst_QScriptEngine::functionScopes()
 {
     QScriptEngine eng;
@@ -4737,6 +4864,25 @@
     QVERIFY(widget == 0);
 }
 
+static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng)
+{
+    Q_ASSERT(ctx->isCalledAsConstructor());
+    return eng->newQObject(ctx->thisObject(), new QObject, QScriptEngine::ScriptOwnership);
+}
+
+void tst_QScriptEngine::promoteThisObjectToQObjectInConstructor()
+{
+    QScriptEngine engine;
+    QScriptValue ctor = engine.newFunction(constructQObjectFromThisObject);
+    engine.globalObject().setProperty("Ctor", ctor);
+    QScriptValue object = engine.evaluate("new Ctor");
+    QVERIFY(!object.isError());
+    QVERIFY(object.isQObject());
+    QVERIFY(object.toQObject() != 0);
+    QVERIFY(object.property("objectName").isString());
+    QVERIFY(object.property("deleteLater").isFunction());
+}
+
 static QRegExp minimal(QRegExp r) { r.setMinimal(true); return r; }
 
 void tst_QScriptEngine::qRegExpInport_data()
@@ -4789,5 +4935,25 @@
     }
 }
 
+static QScriptValue createAnotherEngine(QScriptContext *, QScriptEngine *)
+{
+    QScriptEngine eng;
+    eng.evaluate("function foo(x, y) { return x + y; }" );
+    eng.evaluate("hello = 5; world = 6" );
+    return eng.evaluate("foo(hello,world)").toInt32();
+}
+
+
+void tst_QScriptEngine::reentrency()
+{
+    QScriptEngine eng;
+    eng.globalObject().setProperty("foo", eng.newFunction(createAnotherEngine));
+    eng.evaluate("function bar() { return foo(); }  hello = 9; function getHello() { return hello; }");
+    QCOMPARE(eng.evaluate("foo() + getHello() + foo()").toInt32(), 5+6 + 9 + 5+6);
+    QCOMPARE(eng.evaluate("foo").call().toInt32(), 5+6);
+    QCOMPARE(eng.evaluate("hello").toInt32(), 9);
+    QCOMPARE(eng.evaluate("foo() + hello").toInt32(), 5+6+9);
+}
+
 QTEST_MAIN(tst_QScriptEngine)
 #include "tst_qscriptengine.moc"