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