Home | History | Annotate | Download | only in qscriptvalue
      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     : engine(0)
     25 {
     26 }
     27 
     28 tst_QScriptValue::~tst_QScriptValue()
     29 {
     30     delete engine;
     31 }
     32 
     33 void tst_QScriptValue::dataHelper(InitDataFunction init, DefineDataFunction define)
     34 {
     35     QTest::addColumn<QString>("__expression__");
     36     (this->*init)();
     37     QHash<QString, QScriptValue>::const_iterator it;
     38     for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
     39         m_currentExpression = it.key();
     40         (this->*define)(it.key().toLatin1());
     41     }
     42     m_currentExpression = QString();
     43 }
     44 
     45 QTestData& tst_QScriptValue::newRow(const char* tag)
     46 {
     47     return QTest::newRow(tag) << m_currentExpression;
     48 }
     49 
     50 void tst_QScriptValue::testHelper(TestFunction fun)
     51 {
     52     QFETCH(QString, __expression__);
     53     QScriptValue value = m_values.value(__expression__);
     54     (this->*fun)(__expression__.toLatin1(), value);
     55 }
     56 
     57 
     58 void tst_QScriptValue::ctor()
     59 {
     60     QScriptEngine eng;
     61     {
     62         QScriptValue v;
     63         QCOMPARE(v.isValid(), false);
     64         QCOMPARE(v.engine(), (QScriptEngine*)0);
     65     }
     66     {
     67         QScriptValue v(&eng, QScriptValue::UndefinedValue);
     68         QCOMPARE(v.isValid(), true);
     69         QCOMPARE(v.isUndefined(), true);
     70         QCOMPARE(v.isObject(), false);
     71         QCOMPARE(v.engine(), &eng);
     72     }
     73     {
     74         QScriptValue v(&eng, QScriptValue::NullValue);
     75         QCOMPARE(v.isValid(), true);
     76         QCOMPARE(v.isNull(), true);
     77         QCOMPARE(v.isObject(), false);
     78         QCOMPARE(v.engine(), &eng);
     79     }
     80     {
     81         QScriptValue v(&eng, false);
     82         QCOMPARE(v.isValid(), true);
     83         QCOMPARE(v.isBoolean(), true);
     84         QCOMPARE(v.isBool(), true);
     85         QCOMPARE(v.isObject(), false);
     86         QCOMPARE(v.toBoolean(), false);
     87         QCOMPARE(v.engine(), &eng);
     88     }
     89     {
     90         QScriptValue v(&eng, int(1));
     91         QCOMPARE(v.isValid(), true);
     92         QCOMPARE(v.isNumber(), true);
     93         QCOMPARE(v.isObject(), false);
     94         QCOMPARE(v.toNumber(), 1.0);
     95         QCOMPARE(v.engine(), &eng);
     96     }
     97     {
     98         QScriptValue v(int(0x43211234));
     99         QVERIFY(v.isNumber());
    100         QCOMPARE(v.toInt32(), 0x43211234);
    101     }
    102     {
    103         QScriptValue v(&eng, uint(1));
    104         QCOMPARE(v.isValid(), true);
    105         QCOMPARE(v.isNumber(), true);
    106         QCOMPARE(v.isObject(), false);
    107         QCOMPARE(v.toNumber(), 1.0);
    108         QCOMPARE(v.engine(), &eng);
    109     }
    110     {
    111         QScriptValue v(uint(0x43211234));
    112         QVERIFY(v.isNumber());
    113         QCOMPARE(v.toUInt32(), uint(0x43211234));
    114     }
    115     {
    116         QScriptValue v(&eng, 1.0);
    117         QCOMPARE(v.isValid(), true);
    118         QCOMPARE(v.isNumber(), true);
    119         QCOMPARE(v.isObject(), false);
    120         QCOMPARE(v.toNumber(), 1.0);
    121         QCOMPARE(v.engine(), &eng);
    122     }
    123     {
    124         QScriptValue v(12345678910.5);
    125         QVERIFY(v.isNumber());
    126         QCOMPARE(v.toNumber(), 12345678910.5);
    127     }
    128     {
    129         QScriptValue v(&eng, "ciao");
    130         QCOMPARE(v.isValid(), true);
    131         QCOMPARE(v.isString(), true);
    132         QCOMPARE(v.isObject(), false);
    133         QCOMPARE(v.toString(), QLatin1String("ciao"));
    134         QCOMPARE(v.engine(), &eng);
    135     }
    136     {
    137         QScriptValue v(&eng, QString("ciao"));
    138         QCOMPARE(v.isValid(), true);
    139         QCOMPARE(v.isString(), true);
    140         QCOMPARE(v.isObject(), false);
    141         QCOMPARE(v.toString(), QLatin1String("ciao"));
    142         QCOMPARE(v.engine(), &eng);
    143     }
    144     // copy constructor, operator=
    145     {
    146         QScriptValue v(&eng, 1.0);
    147         QScriptValue v2(v);
    148         QCOMPARE(v2.strictlyEquals(v), true);
    149         QCOMPARE(v2.engine(), &eng);
    150 
    151         QScriptValue v3(v);
    152         QCOMPARE(v3.strictlyEquals(v), true);
    153         QCOMPARE(v3.strictlyEquals(v2), true);
    154         QCOMPARE(v3.engine(), &eng);
    155 
    156         QScriptValue v4(&eng, 2.0);
    157         QCOMPARE(v4.strictlyEquals(v), false);
    158         v3 = v4;
    159         QCOMPARE(v3.strictlyEquals(v), false);
    160         QCOMPARE(v3.strictlyEquals(v4), true);
    161 
    162         v2 = QScriptValue();
    163         QCOMPARE(v2.strictlyEquals(v), false);
    164         QCOMPARE(v.toNumber(), 1.0);
    165 
    166         QScriptValue v5(v);
    167         QCOMPARE(v5.strictlyEquals(v), true);
    168         v = QScriptValue();
    169         QCOMPARE(v5.strictlyEquals(v), false);
    170         QCOMPARE(v5.toNumber(), 1.0);
    171     }
    172 
    173     // constructors that take no engine argument
    174     {
    175         QScriptValue v(QScriptValue::UndefinedValue);
    176         QCOMPARE(v.isValid(), true);
    177         QCOMPARE(v.isUndefined(), true);
    178         QCOMPARE(v.isObject(), false);
    179         QCOMPARE(v.engine(), (QScriptEngine*)0);
    180     }
    181     {
    182         QScriptValue v(QScriptValue::NullValue);
    183         QCOMPARE(v.isValid(), true);
    184         QCOMPARE(v.isNull(), true);
    185         QCOMPARE(v.isObject(), false);
    186         QCOMPARE(v.engine(), (QScriptEngine*)0);
    187     }
    188     {
    189         QScriptValue v(false);
    190         QCOMPARE(v.isValid(), true);
    191         QCOMPARE(v.isBoolean(), true);
    192         QCOMPARE(v.isBool(), true);
    193         QCOMPARE(v.isObject(), false);
    194         QCOMPARE(v.toBoolean(), false);
    195         QCOMPARE(v.engine(), (QScriptEngine*)0);
    196     }
    197     {
    198         QScriptValue v(int(1));
    199         QCOMPARE(v.isValid(), true);
    200         QCOMPARE(v.isNumber(), true);
    201         QCOMPARE(v.isObject(), false);
    202         QCOMPARE(v.toNumber(), 1.0);
    203         QCOMPARE(v.engine(), (QScriptEngine*)0);
    204     }
    205     {
    206         QScriptValue v(uint(1));
    207         QCOMPARE(v.isValid(), true);
    208         QCOMPARE(v.isNumber(), true);
    209         QCOMPARE(v.isObject(), false);
    210         QCOMPARE(v.toNumber(), 1.0);
    211         QCOMPARE(v.engine(), (QScriptEngine*)0);
    212     }
    213     {
    214         QScriptValue v(1.0);
    215         QCOMPARE(v.isValid(), true);
    216         QCOMPARE(v.isNumber(), true);
    217         QCOMPARE(v.isObject(), false);
    218         QCOMPARE(v.toNumber(), 1.0);
    219         QCOMPARE(v.engine(), (QScriptEngine*)0);
    220     }
    221     {
    222         QScriptValue v("ciao");
    223         QCOMPARE(v.isValid(), true);
    224         QCOMPARE(v.isString(), true);
    225         QCOMPARE(v.isObject(), false);
    226         QCOMPARE(v.toString(), QLatin1String("ciao"));
    227         QCOMPARE(v.engine(), (QScriptEngine*)0);
    228     }
    229     {
    230         QScriptValue v(QString("ciao"));
    231         QCOMPARE(v.isValid(), true);
    232         QCOMPARE(v.isString(), true);
    233         QCOMPARE(v.isObject(), false);
    234         QCOMPARE(v.toString(), QLatin1String("ciao"));
    235         QCOMPARE(v.engine(), (QScriptEngine*)0);
    236     }
    237     // copy constructor, operator=
    238     {
    239         QScriptValue v(1.0);
    240         QScriptValue v2(v);
    241         QCOMPARE(v2.strictlyEquals(v), true);
    242         QCOMPARE(v2.engine(), (QScriptEngine*)0);
    243 
    244         QScriptValue v3(v);
    245         QCOMPARE(v3.strictlyEquals(v), true);
    246         QCOMPARE(v3.strictlyEquals(v2), true);
    247         QCOMPARE(v3.engine(), (QScriptEngine*)0);
    248 
    249         QScriptValue v4(2.0);
    250         QCOMPARE(v4.strictlyEquals(v), false);
    251         v3 = v4;
    252         QCOMPARE(v3.strictlyEquals(v), false);
    253         QCOMPARE(v3.strictlyEquals(v4), true);
    254 
    255         v2 = QScriptValue();
    256         QCOMPARE(v2.strictlyEquals(v), false);
    257         QCOMPARE(v.toNumber(), 1.0);
    258 
    259         QScriptValue v5(v);
    260         QCOMPARE(v5.strictlyEquals(v), true);
    261         v = QScriptValue();
    262         QCOMPARE(v5.strictlyEquals(v), false);
    263         QCOMPARE(v5.toNumber(), 1.0);
    264     }
    265 
    266     // 0 engine
    267     QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
    268     QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
    269     QVERIFY(QScriptValue(0, false).isBool());
    270     QVERIFY(QScriptValue(0, int(1)).isNumber());
    271     QVERIFY(QScriptValue(0, uint(1)).isNumber());
    272     QVERIFY(QScriptValue(0, 1.0).isNumber());
    273     QVERIFY(QScriptValue(0, "ciao").isString());
    274     QVERIFY(QScriptValue(0, QString("ciao")).isString());
    275 }
    276 
    277 void tst_QScriptValue::toString_data()
    278 {
    279     QTest::addColumn<QString>("code");
    280     QTest::addColumn<QString>("result");
    281 
    282     QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello");
    283     QTest::newRow("string utf") << QString::fromUtf8("''") << QString::fromUtf8("");
    284     QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5");
    285     QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null");
    286     QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false");
    287     QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined");
    288     QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]");
    289 }
    290 
    291 /* Test conversion to string from different JSC types */
    292 void tst_QScriptValue::toString()
    293 {
    294     QFETCH(QString, code);
    295     QFETCH(QString, result);
    296 
    297     QScriptEngine engine;
    298     QCOMPARE(engine.evaluate(code).toString(), result);
    299 }
    300 
    301 void tst_QScriptValue::copyConstructor_data()
    302 {
    303     QScriptEngine engine;
    304     QScriptValue nnumber(123);
    305     QScriptValue nstring("ping");
    306     QScriptValue number(engine.evaluate("1"));
    307     QScriptValue string(engine.evaluate("'foo'"));
    308     QScriptValue object(engine.evaluate("new Object"));
    309     QScriptValue undefined(engine.evaluate("undefined"));
    310     QScriptValue null(engine.evaluate("null"));
    311 
    312     QTest::addColumn<QScriptValue>("value");
    313     QTest::addColumn<QString>("result");
    314 
    315     QTest::newRow("native number") << nnumber << QString::number(123);
    316     QTest::newRow("native string") << nstring << QString("ping");
    317     QTest::newRow("number") << number << QString::fromAscii("1");
    318     QTest::newRow("string") << string << QString::fromAscii("foo");
    319     QTest::newRow("object") << object << QString::fromAscii("[object Object]");
    320     QTest::newRow("undefined") << undefined << QString::fromAscii("undefined");
    321     QTest::newRow("null") << null << QString::fromAscii("null");
    322 }
    323 
    324 void tst_QScriptValue::copyConstructor()
    325 {
    326     QFETCH(QScriptValue, value);
    327     QFETCH(QString, result);
    328 
    329     QVERIFY(value.isValid());
    330     QScriptValue tmp(value);
    331     QVERIFY(tmp.isValid());
    332     QCOMPARE(tmp.toString(), result);
    333 }
    334 
    335 void tst_QScriptValue::assignOperator_data()
    336 {
    337     copyConstructor_data();
    338 }
    339 
    340 void tst_QScriptValue::assignOperator()
    341 {
    342     QFETCH(QScriptValue, value);
    343     QFETCH(QString, result);
    344 
    345     QScriptValue tmp;
    346     tmp = value;
    347     QVERIFY(tmp.isValid());
    348     QCOMPARE(tmp.toString(), result);
    349 }
    350 
    351 /* Test internal data sharing between a diffrenet QScriptValue. */
    352 void tst_QScriptValue::dataSharing()
    353 {
    354     QScriptEngine engine;
    355     QScriptValue v1;
    356     QScriptValue v2(v1);
    357 
    358     v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid.
    359     QVERIFY(v1.isValid());
    360     QVERIFY(!v2.isValid());
    361 
    362     v2 = v1; // v1 == 1; v2 == 1.
    363     QVERIFY(v1.isValid());
    364     QVERIFY(v2.isValid());
    365 
    366     v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1.
    367     QVERIFY(v1.isValid());
    368     QVERIFY(v2.isValid());
    369     QVERIFY(v2.toString() != v1.toString());
    370 
    371     // TODO add object manipulation (v1 and v2 point to the same object).
    372 }
    373 
    374 void tst_QScriptValue::constructors_data()
    375 {
    376     QScriptEngine engine;
    377 
    378     QTest::addColumn<QScriptValue>("value");
    379     QTest::addColumn<QString>("string");
    380     QTest::addColumn<bool>("valid");
    381     QTest::addColumn<bool>("object");
    382 
    383     QTest::newRow("invalid") << QScriptValue() << QString() << false << false;
    384     QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false;
    385     QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false;
    386     QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false;
    387     QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false;
    388     QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true;
    389     QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false;
    390     QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false;
    391 }
    392 
    393 void tst_QScriptValue::constructors()
    394 {
    395     QFETCH(QScriptValue, value);
    396     QFETCH(QString, string);
    397     QFETCH(bool, valid);
    398     QFETCH(bool, object);
    399 
    400     QCOMPARE(value.isValid(), valid);
    401     QCOMPARE(value.toString(), string);
    402     QCOMPARE(value.isObject(), object);
    403 }
    404 
    405 void tst_QScriptValue::call()
    406 {
    407     QScriptEngine engine;
    408     QScriptValue ping = engine.evaluate("( function() {return 'ping';} )");
    409     QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )");
    410     QScriptValue one(1);
    411     QScriptValue five(5);
    412     QScriptValue result;
    413 
    414     QVERIFY(one.isValid());
    415     QVERIFY(five.isValid());
    416 
    417     QVERIFY(ping.isValid());
    418     QVERIFY(ping.isFunction());
    419     result = ping.call();
    420     QVERIFY(result.isValid());
    421     QCOMPARE(result.toString(), QString::fromUtf8("ping"));
    422 
    423     QVERIFY(incr.isValid());
    424     QVERIFY(incr.isFunction());
    425     result = incr.call(QScriptValue(), QScriptValueList() << one);
    426     QVERIFY(result.isValid());
    427     QCOMPARE(result.toString(), QString("2"));
    428 
    429     QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6"));
    430 
    431     QVERIFY(incr.call().isValid()); // Exception.
    432 }
    433 
    434 
    435 QTEST_MAIN(tst_QScriptValue)
    436