1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "tst_qscriptvalue.h"
30#include <QtWidgets/QPushButton>
31
32QT_BEGIN_NAMESPACE
33extern bool qt_script_isJITEnabled();
34QT_END_NAMESPACE
35
36tst_QScriptValue::tst_QScriptValue()
37 : engine(0)
38{
39}
40
41tst_QScriptValue::~tst_QScriptValue()
42{
43 if (engine)
44 delete engine;
45}
46
47void tst_QScriptValue::ctor_invalid()
48{
49 QScriptEngine eng;
50 {
51 QScriptValue v;
52 QCOMPARE(v.isValid(), false);
53 QCOMPARE(v.engine(), (QScriptEngine *)0);
54 }
55}
56
57void tst_QScriptValue::ctor_undefinedWithEngine()
58{
59 QScriptEngine eng;
60 {
61 QScriptValue v(&eng, QScriptValue::UndefinedValue);
62 QCOMPARE(v.isValid(), true);
63 QCOMPARE(v.isUndefined(), true);
64 QCOMPARE(v.isObject(), false);
65 QCOMPARE(v.engine(), &eng);
66 }
67}
68
69void tst_QScriptValue::ctor_nullWithEngine()
70{
71 QScriptEngine eng;
72 {
73 QScriptValue v(&eng, QScriptValue::NullValue);
74 QCOMPARE(v.isValid(), true);
75 QCOMPARE(v.isNull(), true);
76 QCOMPARE(v.isObject(), false);
77 QCOMPARE(v.engine(), &eng);
78 }
79}
80
81void tst_QScriptValue::ctor_boolWithEngine()
82{
83 QScriptEngine eng;
84 {
85 QScriptValue v(&eng, false);
86 QCOMPARE(v.isValid(), true);
87 QCOMPARE(v.isBoolean(), true);
88 QCOMPARE(v.isBool(), true);
89 QCOMPARE(v.isObject(), false);
90 QCOMPARE(v.toBoolean(), false);
91 QCOMPARE(v.engine(), &eng);
92 }
93}
94
95void tst_QScriptValue::ctor_intWithEngine()
96{
97 QScriptEngine eng;
98 {
99 QScriptValue v(&eng, int(1));
100 QCOMPARE(v.isValid(), true);
101 QCOMPARE(v.isNumber(), true);
102 QCOMPARE(v.isObject(), false);
103 QCOMPARE(v.toNumber(), 1.0);
104 QCOMPARE(v.engine(), &eng);
105 }
106}
107
108void tst_QScriptValue::ctor_int()
109{
110 {
111 QScriptValue v(int(0x43211234));
112 QVERIFY(v.isNumber());
113 QCOMPARE(v.toInt32(), 0x43211234);
114 }
115 {
116 QScriptValue v(int(1));
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(), (QScriptEngine *)0);
122 }
123}
124
125void tst_QScriptValue::ctor_uintWithEngine()
126{
127 QScriptEngine eng;
128 {
129 QScriptValue v(&eng, uint(1));
130 QCOMPARE(v.isValid(), true);
131 QCOMPARE(v.isNumber(), true);
132 QCOMPARE(v.isObject(), false);
133 QCOMPARE(v.toNumber(), 1.0);
134 QCOMPARE(v.engine(), &eng);
135 }
136}
137
138void tst_QScriptValue::ctor_uint()
139{
140 {
141 QScriptValue v(uint(0x43211234));
142 QVERIFY(v.isNumber());
143 QCOMPARE(v.toUInt32(), uint(0x43211234));
144 }
145 {
146 QScriptValue v(uint(1));
147 QCOMPARE(v.isValid(), true);
148 QCOMPARE(v.isNumber(), true);
149 QCOMPARE(v.isObject(), false);
150 QCOMPARE(v.toNumber(), 1.0);
151 QCOMPARE(v.engine(), (QScriptEngine *)0);
152 }
153}
154
155void tst_QScriptValue::ctor_floatWithEngine()
156{
157 QScriptEngine eng;
158 {
159 QScriptValue v(&eng, 1.0);
160 QCOMPARE(v.isValid(), true);
161 QCOMPARE(v.isNumber(), true);
162 QCOMPARE(v.isObject(), false);
163 QCOMPARE(v.toNumber(), 1.0);
164 QCOMPARE(v.engine(), &eng);
165 }
166}
167
168void tst_QScriptValue::ctor_float()
169{
170 {
171 QScriptValue v(12345678910.5);
172 QVERIFY(v.isNumber());
173 QCOMPARE(v.toNumber(), 12345678910.5);
174 }
175 {
176 QScriptValue v(1.0);
177 QCOMPARE(v.isValid(), true);
178 QCOMPARE(v.isNumber(), true);
179 QCOMPARE(v.isObject(), false);
180 QCOMPARE(v.toNumber(), 1.0);
181 QCOMPARE(v.engine(), (QScriptEngine *)0);
182 }
183}
184
185void tst_QScriptValue::ctor_stringWithEngine()
186{
187 QScriptEngine eng;
188 {
189 QScriptValue v(&eng, "ciao");
190 QCOMPARE(v.isValid(), true);
191 QCOMPARE(v.isString(), true);
192 QCOMPARE(v.isObject(), false);
193 QCOMPARE(v.toString(), QLatin1String("ciao"));
194 QCOMPARE(v.engine(), &eng);
195 }
196}
197
198void tst_QScriptValue::ctor_string()
199{
200 {
201 QScriptValue v(QString("ciao"));
202 QCOMPARE(v.isValid(), true);
203 QCOMPARE(v.isString(), true);
204 QCOMPARE(v.isObject(), false);
205 QCOMPARE(v.toString(), QLatin1String("ciao"));
206 QCOMPARE(v.engine(), (QScriptEngine *)0);
207 }
208 {
209 QScriptValue v("ciao");
210 QCOMPARE(v.isValid(), true);
211 QCOMPARE(v.isString(), true);
212 QCOMPARE(v.isObject(), false);
213 QCOMPARE(v.toString(), QLatin1String("ciao"));
214 QCOMPARE(v.engine(), (QScriptEngine *)0);
215 }
216}
217
218void tst_QScriptValue::ctor_copyAndAssignWithEngine()
219{
220 QScriptEngine eng;
221 // copy constructor, operator=
222 {
223 QScriptValue v(&eng, 1.0);
224 QScriptValue v2(v);
225 QCOMPARE(v2.strictlyEquals(v), true);
226 QCOMPARE(v2.engine(), &eng);
227
228 QScriptValue v3(v);
229 QCOMPARE(v3.strictlyEquals(v), true);
230 QCOMPARE(v3.strictlyEquals(v2), true);
231 QCOMPARE(v3.engine(), &eng);
232
233 QScriptValue v4(&eng, 2.0);
234 QCOMPARE(v4.strictlyEquals(v), false);
235 v3 = v4;
236 QCOMPARE(v3.strictlyEquals(v), false);
237 QCOMPARE(v3.strictlyEquals(v4), true);
238
239 v2 = QScriptValue();
240 QCOMPARE(v2.strictlyEquals(v), false);
241 QCOMPARE(v.toNumber(), 1.0);
242
243 QScriptValue v5(v);
244 QCOMPARE(v5.strictlyEquals(v), true);
245 v = QScriptValue();
246 QCOMPARE(v5.strictlyEquals(v), false);
247 QCOMPARE(v5.toNumber(), 1.0);
248 }
249}
250
251void tst_QScriptValue::ctor_undefined()
252{
253 QScriptValue v(QScriptValue::UndefinedValue);
254 QCOMPARE(v.isValid(), true);
255 QCOMPARE(v.isUndefined(), true);
256 QCOMPARE(v.isObject(), false);
257 QCOMPARE(v.engine(), (QScriptEngine *)0);
258}
259
260void tst_QScriptValue::ctor_null()
261{
262 QScriptValue v(QScriptValue::NullValue);
263 QCOMPARE(v.isValid(), true);
264 QCOMPARE(v.isNull(), true);
265 QCOMPARE(v.isObject(), false);
266 QCOMPARE(v.engine(), (QScriptEngine *)0);
267}
268
269void tst_QScriptValue::ctor_bool()
270{
271 QScriptValue v(false);
272 QCOMPARE(v.isValid(), true);
273 QCOMPARE(v.isBoolean(), true);
274 QCOMPARE(v.isBool(), true);
275 QCOMPARE(v.isObject(), false);
276 QCOMPARE(v.toBoolean(), false);
277 QCOMPARE(v.engine(), (QScriptEngine *)0);
278}
279
280void tst_QScriptValue::ctor_copyAndAssign()
281{
282 QScriptValue v(1.0);
283 QScriptValue v2(v);
284 QCOMPARE(v2.strictlyEquals(v), true);
285 QCOMPARE(v2.engine(), (QScriptEngine *)0);
286
287 QScriptValue v3(v);
288 QCOMPARE(v3.strictlyEquals(v), true);
289 QCOMPARE(v3.strictlyEquals(v2), true);
290 QCOMPARE(v3.engine(), (QScriptEngine *)0);
291
292 QScriptValue v4(2.0);
293 QCOMPARE(v4.strictlyEquals(v), false);
294 v3 = v4;
295 QCOMPARE(v3.strictlyEquals(v), false);
296 QCOMPARE(v3.strictlyEquals(v4), true);
297
298 v2 = QScriptValue();
299 QCOMPARE(v2.strictlyEquals(v), false);
300 QCOMPARE(v.toNumber(), 1.0);
301
302 QScriptValue v5(v);
303 QCOMPARE(v5.strictlyEquals(v), true);
304 v = QScriptValue();
305 QCOMPARE(v5.strictlyEquals(v), false);
306 QCOMPARE(v5.toNumber(), 1.0);
307}
308
309void tst_QScriptValue::ctor_nullEngine()
310{
311 // 0 engine
312 QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
313 QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
314 QVERIFY(QScriptValue(0, false).isBool());
315 QVERIFY(QScriptValue(0, int(1)).isNumber());
316 QVERIFY(QScriptValue(0, uint(1)).isNumber());
317 QVERIFY(QScriptValue(0, 1.0).isNumber());
318 QVERIFY(QScriptValue(0, "ciao").isString());
319 QVERIFY(QScriptValue(0, QString("ciao")).isString());
320}
321
322static QScriptValue myFunction(QScriptContext *, QScriptEngine *eng)
323{
324 return eng->undefinedValue();
325}
326
327void tst_QScriptValue::toString()
328{
329 QScriptEngine eng;
330
331 QScriptValue undefined = eng.undefinedValue();
332 QCOMPARE(undefined.toString(), QString("undefined"));
333 QCOMPARE(qscriptvalue_cast<QString>(undefined), QString());
334
335 QScriptValue null = eng.nullValue();
336 QCOMPARE(null.toString(), QString("null"));
337 QCOMPARE(qscriptvalue_cast<QString>(null), QString());
338
339 {
340 QScriptValue falskt = QScriptValue(&eng, false);
341 QCOMPARE(falskt.toString(), QString("false"));
342 QCOMPARE(qscriptvalue_cast<QString>(falskt), QString("false"));
343
344 QScriptValue sant = QScriptValue(&eng, true);
345 QCOMPARE(sant.toString(), QString("true"));
346 QCOMPARE(qscriptvalue_cast<QString>(sant), QString("true"));
347 }
348 {
349 QScriptValue number = QScriptValue(&eng, 123);
350 QCOMPARE(number.toString(), QString("123"));
351 QCOMPARE(qscriptvalue_cast<QString>(number), QString("123"));
352 }
353 {
354 QScriptValue number = QScriptValue(&eng, 6.37e-8);
355 QCOMPARE(number.toString(), QString("6.37e-8"));
356 }
357 {
358 QScriptValue number = QScriptValue(&eng, -6.37e-8);
359 QCOMPARE(number.toString(), QString("-6.37e-8"));
360
361 QScriptValue str = QScriptValue(&eng, QString("ciao"));
362 QCOMPARE(str.toString(), QString("ciao"));
363 QCOMPARE(qscriptvalue_cast<QString>(str), QString("ciao"));
364 }
365
366 QScriptValue object = eng.newObject();
367 QCOMPARE(object.toString(), QString("[object Object]"));
368 QCOMPARE(qscriptvalue_cast<QString>(object), QString("[object Object]"));
369
370 QScriptValue fun = eng.newFunction(signature: myFunction);
371 QCOMPARE(fun.toString(), QString("function () {\n [native code]\n}"));
372 QCOMPARE(qscriptvalue_cast<QString>(fun), QString("function () {\n [native code]\n}"));
373
374 // toString() that throws exception
375 {
376 QScriptValue objectObject = eng.evaluate(
377 program: "(function(){"
378 " o = { };"
379 " o.toString = function() { throw new Error('toString'); };"
380 " return o;"
381 "})()");
382 QCOMPARE(objectObject.toString(), QLatin1String("Error: toString"));
383 QVERIFY(eng.hasUncaughtException());
384 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: toString"));
385 }
386 {
387 eng.clearExceptions();
388 QScriptValue objectObject = eng.evaluate(
389 program: "(function(){"
390 " var f = function() {};"
391 " f.prototype = Date;"
392 " return new f;"
393 "})()");
394 QVERIFY(!eng.hasUncaughtException());
395 QVERIFY(objectObject.isObject());
396 QCOMPARE(objectObject.toString(), QString::fromLatin1("TypeError: Function.prototype.toString called on incompatible object"));
397 QVERIFY(eng.hasUncaughtException());
398 eng.clearExceptions();
399 }
400
401 QScriptValue inv = QScriptValue();
402 QCOMPARE(inv.toString(), QString());
403
404 // V2 constructors
405 {
406 QScriptValue falskt = QScriptValue(false);
407 QCOMPARE(falskt.toString(), QString("false"));
408 QCOMPARE(qscriptvalue_cast<QString>(falskt), QString("false"));
409
410 QScriptValue sant = QScriptValue(true);
411 QCOMPARE(sant.toString(), QString("true"));
412 QCOMPARE(qscriptvalue_cast<QString>(sant), QString("true"));
413
414 QScriptValue number = QScriptValue(123);
415 QCOMPARE(number.toString(), QString("123"));
416 QCOMPARE(qscriptvalue_cast<QString>(number), QString("123"));
417
418 QScriptValue number2(int(0x43211234));
419 QCOMPARE(number2.toString(), QString("1126240820"));
420
421 QScriptValue str = QScriptValue(QString("ciao"));
422 QCOMPARE(str.toString(), QString("ciao"));
423 QCOMPARE(qscriptvalue_cast<QString>(str), QString("ciao"));
424 }
425
426 // variant should use internal valueOf(), then fall back to QVariant::toString(),
427 // then fall back to "QVariant(typename)"
428 QScriptValue variant = eng.newVariant(value: 123);
429 QVERIFY(variant.isVariant());
430 QCOMPARE(variant.toString(), QString::fromLatin1("123"));
431 variant = eng.newVariant(value: QByteArray("hello"));
432 QVERIFY(variant.isVariant());
433 QCOMPARE(variant.toString(), QString::fromLatin1("hello"));
434 variant = eng.newVariant(value: QVariant(QPoint(10, 20)));
435 QVERIFY(variant.isVariant());
436 QCOMPARE(variant.toString(), QString::fromLatin1("QVariant(QPoint)"));
437 variant = eng.newVariant(value: QUrl());
438 QVERIFY(variant.toString().isEmpty());
439}
440
441void tst_QScriptValue::toNumber()
442{
443 QScriptEngine eng;
444
445 QScriptValue undefined = eng.undefinedValue();
446 QCOMPARE(qIsNaN(undefined.toNumber()), true);
447 QCOMPARE(qIsNaN(qscriptvalue_cast<qsreal>(undefined)), true);
448
449 QScriptValue null = eng.nullValue();
450 QCOMPARE(null.toNumber(), 0.0);
451 QCOMPARE(qscriptvalue_cast<qsreal>(null), 0.0);
452
453 {
454 QScriptValue falskt = QScriptValue(&eng, false);
455 QCOMPARE(falskt.toNumber(), 0.0);
456 QCOMPARE(qscriptvalue_cast<qsreal>(falskt), 0.0);
457
458 QScriptValue sant = QScriptValue(&eng, true);
459 QCOMPARE(sant.toNumber(), 1.0);
460 QCOMPARE(qscriptvalue_cast<qsreal>(sant), 1.0);
461
462 QScriptValue number = QScriptValue(&eng, 123.0);
463 QCOMPARE(number.toNumber(), 123.0);
464 QCOMPARE(qscriptvalue_cast<qsreal>(number), 123.0);
465
466 QScriptValue str = QScriptValue(&eng, QString("ciao"));
467 QCOMPARE(qIsNaN(str.toNumber()), true);
468 QCOMPARE(qIsNaN(qscriptvalue_cast<qsreal>(str)), true);
469
470 QScriptValue str2 = QScriptValue(&eng, QString("123"));
471 QCOMPARE(str2.toNumber(), 123.0);
472 QCOMPARE(qscriptvalue_cast<qsreal>(str2), 123.0);
473 }
474
475 QScriptValue object = eng.newObject();
476 QCOMPARE(qIsNaN(object.toNumber()), true);
477 QCOMPARE(qIsNaN(qscriptvalue_cast<qsreal>(object)), true);
478
479 QScriptValue fun = eng.newFunction(signature: myFunction);
480 QCOMPARE(qIsNaN(fun.toNumber()), true);
481 QCOMPARE(qIsNaN(qscriptvalue_cast<qsreal>(fun)), true);
482
483 QScriptValue inv = QScriptValue();
484 QCOMPARE(inv.toNumber(), 0.0);
485 QCOMPARE(qscriptvalue_cast<qsreal>(inv), 0.0);
486
487 // V2 constructors
488 {
489 QScriptValue falskt = QScriptValue(false);
490 QCOMPARE(falskt.toNumber(), 0.0);
491 QCOMPARE(qscriptvalue_cast<qsreal>(falskt), 0.0);
492
493 QScriptValue sant = QScriptValue(true);
494 QCOMPARE(sant.toNumber(), 1.0);
495 QCOMPARE(qscriptvalue_cast<qsreal>(sant), 1.0);
496
497 QScriptValue number = QScriptValue(123.0);
498 QCOMPARE(number.toNumber(), 123.0);
499 QCOMPARE(qscriptvalue_cast<qsreal>(number), 123.0);
500
501 QScriptValue number2(int(0x43211234));
502 QCOMPARE(number2.toNumber(), 1126240820.0);
503
504 QScriptValue str = QScriptValue(QString("ciao"));
505 QCOMPARE(qIsNaN(str.toNumber()), true);
506 QCOMPARE(qIsNaN(qscriptvalue_cast<qsreal>(str)), true);
507
508 QScriptValue str2 = QScriptValue(QString("123"));
509 QCOMPARE(str2.toNumber(), 123.0);
510 QCOMPARE(qscriptvalue_cast<qsreal>(str2), 123.0);
511 }
512}
513
514void tst_QScriptValue::toBoolean() // deprecated
515{
516 QScriptEngine eng;
517
518 QScriptValue undefined = eng.undefinedValue();
519 QCOMPARE(undefined.toBoolean(), false);
520 QCOMPARE(qscriptvalue_cast<bool>(undefined), false);
521
522 QScriptValue null = eng.nullValue();
523 QCOMPARE(null.toBoolean(), false);
524 QCOMPARE(qscriptvalue_cast<bool>(null), false);
525
526 {
527 QScriptValue falskt = QScriptValue(&eng, false);
528 QCOMPARE(falskt.toBoolean(), false);
529 QCOMPARE(qscriptvalue_cast<bool>(falskt), false);
530
531 QScriptValue sant = QScriptValue(&eng, true);
532 QCOMPARE(sant.toBoolean(), true);
533 QCOMPARE(qscriptvalue_cast<bool>(sant), true);
534
535 QScriptValue number = QScriptValue(&eng, 0.0);
536 QCOMPARE(number.toBoolean(), false);
537 QCOMPARE(qscriptvalue_cast<bool>(number), false);
538
539 QScriptValue number2 = QScriptValue(&eng, qSNaN());
540 QCOMPARE(number2.toBoolean(), false);
541 QCOMPARE(qscriptvalue_cast<bool>(number2), false);
542
543 QScriptValue number3 = QScriptValue(&eng, 123.0);
544 QCOMPARE(number3.toBoolean(), true);
545 QCOMPARE(qscriptvalue_cast<bool>(number3), true);
546
547 QScriptValue number4 = QScriptValue(&eng, -456.0);
548 QCOMPARE(number4.toBoolean(), true);
549 QCOMPARE(qscriptvalue_cast<bool>(number4), true);
550
551 QScriptValue str = QScriptValue(&eng, QString(""));
552 QCOMPARE(str.toBoolean(), false);
553 QCOMPARE(qscriptvalue_cast<bool>(str), false);
554
555 QScriptValue str2 = QScriptValue(&eng, QString("123"));
556 QCOMPARE(str2.toBoolean(), true);
557 QCOMPARE(qscriptvalue_cast<bool>(str2), true);
558 }
559
560 QScriptValue object = eng.newObject();
561 QCOMPARE(object.toBoolean(), true);
562 QCOMPARE(qscriptvalue_cast<bool>(object), true);
563
564 QScriptValue fun = eng.newFunction(signature: myFunction);
565 QCOMPARE(fun.toBoolean(), true);
566 QCOMPARE(qscriptvalue_cast<bool>(fun), true);
567
568 QScriptValue inv = QScriptValue();
569 QCOMPARE(inv.toBoolean(), false);
570 QCOMPARE(qscriptvalue_cast<bool>(inv), false);
571
572 // V2 constructors
573 {
574 QScriptValue falskt = QScriptValue(false);
575 QCOMPARE(falskt.toBoolean(), false);
576 QCOMPARE(qscriptvalue_cast<bool>(falskt), false);
577
578 QScriptValue sant = QScriptValue(true);
579 QCOMPARE(sant.toBoolean(), true);
580 QCOMPARE(qscriptvalue_cast<bool>(sant), true);
581
582 QScriptValue number = QScriptValue(0.0);
583 QCOMPARE(number.toBoolean(), false);
584 QCOMPARE(qscriptvalue_cast<bool>(number), false);
585
586 QScriptValue number2 = QScriptValue(qSNaN());
587 QCOMPARE(number2.toBoolean(), false);
588 QCOMPARE(qscriptvalue_cast<bool>(number2), false);
589
590 QScriptValue number3 = QScriptValue(123.0);
591 QCOMPARE(number3.toBoolean(), true);
592 QCOMPARE(qscriptvalue_cast<bool>(number3), true);
593
594 QScriptValue number4 = QScriptValue(-456.0);
595 QCOMPARE(number4.toBoolean(), true);
596 QCOMPARE(qscriptvalue_cast<bool>(number4), true);
597
598 QScriptValue number5 = QScriptValue(0x43211234);
599 QCOMPARE(number5.toBoolean(), true);
600
601 QScriptValue str = QScriptValue(QString(""));
602 QCOMPARE(str.toBoolean(), false);
603 QCOMPARE(qscriptvalue_cast<bool>(str), false);
604
605 QScriptValue str2 = QScriptValue(QString("123"));
606 QCOMPARE(str2.toBoolean(), true);
607 QCOMPARE(qscriptvalue_cast<bool>(str2), true);
608 }
609}
610
611void tst_QScriptValue::toBool()
612{
613 QScriptEngine eng;
614
615 QScriptValue undefined = eng.undefinedValue();
616 QCOMPARE(undefined.toBool(), false);
617 QCOMPARE(qscriptvalue_cast<bool>(undefined), false);
618
619 QScriptValue null = eng.nullValue();
620 QCOMPARE(null.toBool(), false);
621 QCOMPARE(qscriptvalue_cast<bool>(null), false);
622
623 {
624 QScriptValue falskt = QScriptValue(&eng, false);
625 QCOMPARE(falskt.toBool(), false);
626 QCOMPARE(qscriptvalue_cast<bool>(falskt), false);
627
628 QScriptValue sant = QScriptValue(&eng, true);
629 QCOMPARE(sant.toBool(), true);
630 QCOMPARE(qscriptvalue_cast<bool>(sant), true);
631
632 QScriptValue number = QScriptValue(&eng, 0.0);
633 QCOMPARE(number.toBool(), false);
634 QCOMPARE(qscriptvalue_cast<bool>(number), false);
635
636 QScriptValue number2 = QScriptValue(&eng, qSNaN());
637 QCOMPARE(number2.toBool(), false);
638 QCOMPARE(qscriptvalue_cast<bool>(number2), false);
639
640 QScriptValue number3 = QScriptValue(&eng, 123.0);
641 QCOMPARE(number3.toBool(), true);
642 QCOMPARE(qscriptvalue_cast<bool>(number3), true);
643
644 QScriptValue number4 = QScriptValue(&eng, -456.0);
645 QCOMPARE(number4.toBool(), true);
646 QCOMPARE(qscriptvalue_cast<bool>(number4), true);
647
648 QScriptValue str = QScriptValue(&eng, QString(""));
649 QCOMPARE(str.toBool(), false);
650 QCOMPARE(qscriptvalue_cast<bool>(str), false);
651
652 QScriptValue str2 = QScriptValue(&eng, QString("123"));
653 QCOMPARE(str2.toBool(), true);
654 QCOMPARE(qscriptvalue_cast<bool>(str2), true);
655 }
656
657 QScriptValue object = eng.newObject();
658 QCOMPARE(object.toBool(), true);
659 QCOMPARE(qscriptvalue_cast<bool>(object), true);
660
661 QScriptValue fun = eng.newFunction(signature: myFunction);
662 QCOMPARE(fun.toBool(), true);
663 QCOMPARE(qscriptvalue_cast<bool>(fun), true);
664
665 QScriptValue inv = QScriptValue();
666 QCOMPARE(inv.toBool(), false);
667 QCOMPARE(qscriptvalue_cast<bool>(inv), false);
668
669 // V2 constructors
670 {
671 QScriptValue falskt = QScriptValue(false);
672 QCOMPARE(falskt.toBool(), false);
673 QCOMPARE(qscriptvalue_cast<bool>(falskt), false);
674
675 QScriptValue sant = QScriptValue(true);
676 QCOMPARE(sant.toBool(), true);
677 QCOMPARE(qscriptvalue_cast<bool>(sant), true);
678
679 QScriptValue number = QScriptValue(0.0);
680 QCOMPARE(number.toBool(), false);
681 QCOMPARE(qscriptvalue_cast<bool>(number), false);
682
683 QScriptValue number2 = QScriptValue(qSNaN());
684 QCOMPARE(number2.toBool(), false);
685 QCOMPARE(qscriptvalue_cast<bool>(number2), false);
686
687 QScriptValue number3 = QScriptValue(123.0);
688 QCOMPARE(number3.toBool(), true);
689 QCOMPARE(qscriptvalue_cast<bool>(number3), true);
690
691 QScriptValue number4 = QScriptValue(-456.0);
692 QCOMPARE(number4.toBool(), true);
693 QCOMPARE(qscriptvalue_cast<bool>(number4), true);
694
695 QScriptValue number5 = QScriptValue(0x43211234);
696 QCOMPARE(number5.toBool(), true);
697
698 QScriptValue str = QScriptValue(QString(""));
699 QCOMPARE(str.toBool(), false);
700 QCOMPARE(qscriptvalue_cast<bool>(str), false);
701
702 QScriptValue str2 = QScriptValue(QString("123"));
703 QCOMPARE(str2.toBool(), true);
704 QCOMPARE(qscriptvalue_cast<bool>(str2), true);
705 }
706}
707
708void tst_QScriptValue::toInteger()
709{
710 QScriptEngine eng;
711
712 {
713 QScriptValue number = QScriptValue(&eng, 123.0);
714 QCOMPARE(number.toInteger(), 123.0);
715
716 QScriptValue number2 = QScriptValue(&eng, qSNaN());
717 QCOMPARE(number2.toInteger(), 0.0);
718
719 QScriptValue number3 = QScriptValue(&eng, qInf());
720 QCOMPARE(qIsInf(number3.toInteger()), true);
721
722 QScriptValue number4 = QScriptValue(&eng, 0.5);
723 QCOMPARE(number4.toInteger(), 0.0);
724
725 QScriptValue number5 = QScriptValue(&eng, 123.5);
726 QCOMPARE(number5.toInteger(), 123.0);
727
728 QScriptValue number6 = QScriptValue(&eng, -456.5);
729 QCOMPARE(number6.toInteger(), -456.0);
730
731 QScriptValue str = QScriptValue(&eng, "123.0");
732 QCOMPARE(str.toInteger(), 123.0);
733
734 QScriptValue str2 = QScriptValue(&eng, "NaN");
735 QCOMPARE(str2.toInteger(), 0.0);
736
737 QScriptValue str3 = QScriptValue(&eng, "Infinity");
738 QCOMPARE(qIsInf(str3.toInteger()), true);
739
740 QScriptValue str4 = QScriptValue(&eng, "0.5");
741 QCOMPARE(str4.toInteger(), 0.0);
742
743 QScriptValue str5 = QScriptValue(&eng, "123.5");
744 QCOMPARE(str5.toInteger(), 123.0);
745
746 QScriptValue str6 = QScriptValue(&eng, "-456.5");
747 QCOMPARE(str6.toInteger(), -456.0);
748 }
749 // V2 constructors
750 {
751 QScriptValue number = QScriptValue(123.0);
752 QCOMPARE(number.toInteger(), 123.0);
753
754 QScriptValue number2 = QScriptValue(qSNaN());
755 QCOMPARE(number2.toInteger(), 0.0);
756
757 QScriptValue number3 = QScriptValue(qInf());
758 QCOMPARE(qIsInf(number3.toInteger()), true);
759
760 QScriptValue number4 = QScriptValue(0.5);
761 QCOMPARE(number4.toInteger(), 0.0);
762
763 QScriptValue number5 = QScriptValue(123.5);
764 QCOMPARE(number5.toInteger(), 123.0);
765
766 QScriptValue number6 = QScriptValue(-456.5);
767 QCOMPARE(number6.toInteger(), -456.0);
768
769 QScriptValue number7 = QScriptValue(0x43211234);
770 QCOMPARE(number7.toInteger(), qsreal(0x43211234));
771
772 QScriptValue str = QScriptValue("123.0");
773 QCOMPARE(str.toInteger(), 123.0);
774
775 QScriptValue str2 = QScriptValue("NaN");
776 QCOMPARE(str2.toInteger(), 0.0);
777
778 QScriptValue str3 = QScriptValue("Infinity");
779 QCOMPARE(qIsInf(str3.toInteger()), true);
780
781 QScriptValue str4 = QScriptValue("0.5");
782 QCOMPARE(str4.toInteger(), 0.0);
783
784 QScriptValue str5 = QScriptValue("123.5");
785 QCOMPARE(str5.toInteger(), 123.0);
786
787 QScriptValue str6 = QScriptValue("-456.5");
788 QCOMPARE(str6.toInteger(), -456.0);
789 }
790
791 QScriptValue inv;
792 QCOMPARE(inv.toInteger(), 0.0);
793}
794
795void tst_QScriptValue::toInt32()
796{
797 QScriptEngine eng;
798
799 {
800 QScriptValue zer0 = QScriptValue(&eng, 0.0);
801 QCOMPARE(zer0.toInt32(), 0);
802 QCOMPARE(qscriptvalue_cast<qint32>(zer0), 0);
803
804 QScriptValue number = QScriptValue(&eng, 123.0);
805 QCOMPARE(number.toInt32(), 123);
806 QCOMPARE(qscriptvalue_cast<qint32>(number), 123);
807
808 QScriptValue number2 = QScriptValue(&eng, qSNaN());
809 QCOMPARE(number2.toInt32(), 0);
810 QCOMPARE(qscriptvalue_cast<qint32>(number2), 0);
811
812 QScriptValue number3 = QScriptValue(&eng, +qInf());
813 QCOMPARE(number3.toInt32(), 0);
814 QCOMPARE(qscriptvalue_cast<qint32>(number3), 0);
815
816 QScriptValue number3_2 = QScriptValue(&eng, -qInf());
817 QCOMPARE(number3_2.toInt32(), 0);
818 QCOMPARE(qscriptvalue_cast<qint32>(number3_2), 0);
819
820 QScriptValue number4 = QScriptValue(&eng, 0.5);
821 QCOMPARE(number4.toInt32(), 0);
822 QCOMPARE(qscriptvalue_cast<qint32>(number4), 0);
823
824 QScriptValue number5 = QScriptValue(&eng, 123.5);
825 QCOMPARE(number5.toInt32(), 123);
826 QCOMPARE(qscriptvalue_cast<qint32>(number5), 123);
827
828 QScriptValue number6 = QScriptValue(&eng, -456.5);
829 QCOMPARE(number6.toInt32(), -456);
830 QCOMPARE(qscriptvalue_cast<qint32>(number6), -456);
831
832 QScriptValue str = QScriptValue(&eng, "123.0");
833 QCOMPARE(str.toInt32(), 123);
834 QCOMPARE(qscriptvalue_cast<qint32>(str), 123);
835
836 QScriptValue str2 = QScriptValue(&eng, "NaN");
837 QCOMPARE(str2.toInt32(), 0);
838 QCOMPARE(qscriptvalue_cast<qint32>(str2), 0);
839
840 QScriptValue str3 = QScriptValue(&eng, "Infinity");
841 QCOMPARE(str3.toInt32(), 0);
842 QCOMPARE(qscriptvalue_cast<qint32>(str3), 0);
843
844 QScriptValue str3_2 = QScriptValue(&eng, "-Infinity");
845 QCOMPARE(str3_2.toInt32(), 0);
846 QCOMPARE(qscriptvalue_cast<qint32>(str3_2), 0);
847
848 QScriptValue str4 = QScriptValue(&eng, "0.5");
849 QCOMPARE(str4.toInt32(), 0);
850 QCOMPARE(qscriptvalue_cast<qint32>(str4), 0);
851
852 QScriptValue str5 = QScriptValue(&eng, "123.5");
853 QCOMPARE(str5.toInt32(), 123);
854 QCOMPARE(qscriptvalue_cast<qint32>(str5), 123);
855
856 QScriptValue str6 = QScriptValue(&eng, "-456.5");
857 QCOMPARE(str6.toInt32(), -456);
858 QCOMPARE(qscriptvalue_cast<qint32>(str6), -456);
859 }
860 // V2 constructors
861 {
862 QScriptValue zer0 = QScriptValue(0.0);
863 QCOMPARE(zer0.toInt32(), 0);
864 QCOMPARE(qscriptvalue_cast<qint32>(zer0), 0);
865
866 QScriptValue number = QScriptValue(123.0);
867 QCOMPARE(number.toInt32(), 123);
868 QCOMPARE(qscriptvalue_cast<qint32>(number), 123);
869
870 QScriptValue number2 = QScriptValue(qSNaN());
871 QCOMPARE(number2.toInt32(), 0);
872 QCOMPARE(qscriptvalue_cast<qint32>(number2), 0);
873
874 QScriptValue number3 = QScriptValue(+qInf());
875 QCOMPARE(number3.toInt32(), 0);
876 QCOMPARE(qscriptvalue_cast<qint32>(number3), 0);
877
878 QScriptValue number3_2 = QScriptValue(-qInf());
879 QCOMPARE(number3_2.toInt32(), 0);
880 QCOMPARE(qscriptvalue_cast<qint32>(number3_2), 0);
881
882 QScriptValue number4 = QScriptValue(0.5);
883 QCOMPARE(number4.toInt32(), 0);
884 QCOMPARE(qscriptvalue_cast<qint32>(number4), 0);
885
886 QScriptValue number5 = QScriptValue(123.5);
887 QCOMPARE(number5.toInt32(), 123);
888 QCOMPARE(qscriptvalue_cast<qint32>(number5), 123);
889
890 QScriptValue number6 = QScriptValue(-456.5);
891 QCOMPARE(number6.toInt32(), -456);
892 QCOMPARE(qscriptvalue_cast<qint32>(number6), -456);
893
894 QScriptValue number7 = QScriptValue(0x43211234);
895 QCOMPARE(number7.toInt32(), 0x43211234);
896
897 QScriptValue str = QScriptValue("123.0");
898 QCOMPARE(str.toInt32(), 123);
899 QCOMPARE(qscriptvalue_cast<qint32>(str), 123);
900
901 QScriptValue str2 = QScriptValue("NaN");
902 QCOMPARE(str2.toInt32(), 0);
903 QCOMPARE(qscriptvalue_cast<qint32>(str2), 0);
904
905 QScriptValue str3 = QScriptValue("Infinity");
906 QCOMPARE(str3.toInt32(), 0);
907 QCOMPARE(qscriptvalue_cast<qint32>(str3), 0);
908
909 QScriptValue str3_2 = QScriptValue("-Infinity");
910 QCOMPARE(str3_2.toInt32(), 0);
911 QCOMPARE(qscriptvalue_cast<qint32>(str3_2), 0);
912
913 QScriptValue str4 = QScriptValue("0.5");
914 QCOMPARE(str4.toInt32(), 0);
915 QCOMPARE(qscriptvalue_cast<qint32>(str4), 0);
916
917 QScriptValue str5 = QScriptValue("123.5");
918 QCOMPARE(str5.toInt32(), 123);
919 QCOMPARE(qscriptvalue_cast<qint32>(str5), 123);
920
921 QScriptValue str6 = QScriptValue("-456.5");
922 QCOMPARE(str6.toInt32(), -456);
923 QCOMPARE(qscriptvalue_cast<qint32>(str6), -456);
924 }
925
926 QScriptValue inv;
927 QCOMPARE(inv.toInt32(), 0);
928 QCOMPARE(qscriptvalue_cast<qint32>(inv), 0);
929}
930
931void tst_QScriptValue::toUInt32()
932{
933 QScriptEngine eng;
934
935 {
936 QScriptValue zer0 = QScriptValue(&eng, 0.0);
937 QCOMPARE(zer0.toUInt32(), quint32(0));
938 QCOMPARE(qscriptvalue_cast<quint32>(zer0), quint32(0));
939
940 QScriptValue number = QScriptValue(&eng, 123.0);
941 QCOMPARE(number.toUInt32(), quint32(123));
942 QCOMPARE(qscriptvalue_cast<quint32>(number), quint32(123));
943
944 QScriptValue number2 = QScriptValue(&eng, qSNaN());
945 QCOMPARE(number2.toUInt32(), quint32(0));
946 QCOMPARE(qscriptvalue_cast<quint32>(number2), quint32(0));
947
948 QScriptValue number3 = QScriptValue(&eng, +qInf());
949 QCOMPARE(number3.toUInt32(), quint32(0));
950 QCOMPARE(qscriptvalue_cast<quint32>(number3), quint32(0));
951
952 QScriptValue number3_2 = QScriptValue(&eng, -qInf());
953 QCOMPARE(number3_2.toUInt32(), quint32(0));
954 QCOMPARE(qscriptvalue_cast<quint32>(number3_2), quint32(0));
955
956 QScriptValue number4 = QScriptValue(&eng, 0.5);
957 QCOMPARE(number4.toUInt32(), quint32(0));
958
959 QScriptValue number5 = QScriptValue(&eng, 123.5);
960 QCOMPARE(number5.toUInt32(), quint32(123));
961
962 QScriptValue number6 = QScriptValue(&eng, -456.5);
963 QCOMPARE(number6.toUInt32(), quint32(-456));
964 QCOMPARE(qscriptvalue_cast<quint32>(number6), quint32(-456));
965
966 QScriptValue str = QScriptValue(&eng, "123.0");
967 QCOMPARE(str.toUInt32(), quint32(123));
968 QCOMPARE(qscriptvalue_cast<quint32>(str), quint32(123));
969
970 QScriptValue str2 = QScriptValue(&eng, "NaN");
971 QCOMPARE(str2.toUInt32(), quint32(0));
972 QCOMPARE(qscriptvalue_cast<quint32>(str2), quint32(0));
973
974 QScriptValue str3 = QScriptValue(&eng, "Infinity");
975 QCOMPARE(str3.toUInt32(), quint32(0));
976 QCOMPARE(qscriptvalue_cast<quint32>(str3), quint32(0));
977
978 QScriptValue str3_2 = QScriptValue(&eng, "-Infinity");
979 QCOMPARE(str3_2.toUInt32(), quint32(0));
980 QCOMPARE(qscriptvalue_cast<quint32>(str3_2), quint32(0));
981
982 QScriptValue str4 = QScriptValue(&eng, "0.5");
983 QCOMPARE(str4.toUInt32(), quint32(0));
984 QCOMPARE(qscriptvalue_cast<quint32>(str4), quint32(0));
985
986 QScriptValue str5 = QScriptValue(&eng, "123.5");
987 QCOMPARE(str5.toUInt32(), quint32(123));
988 QCOMPARE(qscriptvalue_cast<quint32>(str5), quint32(123));
989
990 QScriptValue str6 = QScriptValue(&eng, "-456.5");
991 QCOMPARE(str6.toUInt32(), quint32(-456));
992 QCOMPARE(qscriptvalue_cast<quint32>(str6), quint32(-456));
993 }
994 // V2 constructors
995 {
996 QScriptValue zer0 = QScriptValue(0.0);
997 QCOMPARE(zer0.toUInt32(), quint32(0));
998 QCOMPARE(qscriptvalue_cast<quint32>(zer0), quint32(0));
999
1000 QScriptValue number = QScriptValue(123.0);
1001 QCOMPARE(number.toUInt32(), quint32(123));
1002 QCOMPARE(qscriptvalue_cast<quint32>(number), quint32(123));
1003
1004 QScriptValue number2 = QScriptValue(qSNaN());
1005 QCOMPARE(number2.toUInt32(), quint32(0));
1006 QCOMPARE(qscriptvalue_cast<quint32>(number2), quint32(0));
1007
1008 QScriptValue number3 = QScriptValue(+qInf());
1009 QCOMPARE(number3.toUInt32(), quint32(0));
1010 QCOMPARE(qscriptvalue_cast<quint32>(number3), quint32(0));
1011
1012 QScriptValue number3_2 = QScriptValue(-qInf());
1013 QCOMPARE(number3_2.toUInt32(), quint32(0));
1014 QCOMPARE(qscriptvalue_cast<quint32>(number3_2), quint32(0));
1015
1016 QScriptValue number4 = QScriptValue(0.5);
1017 QCOMPARE(number4.toUInt32(), quint32(0));
1018
1019 QScriptValue number5 = QScriptValue(123.5);
1020 QCOMPARE(number5.toUInt32(), quint32(123));
1021
1022 QScriptValue number6 = QScriptValue(-456.5);
1023 QCOMPARE(number6.toUInt32(), quint32(-456));
1024 QCOMPARE(qscriptvalue_cast<quint32>(number6), quint32(-456));
1025
1026 QScriptValue number7 = QScriptValue(0x43211234);
1027 QCOMPARE(number7.toUInt32(), quint32(0x43211234));
1028
1029 QScriptValue str = QScriptValue("123.0");
1030 QCOMPARE(str.toUInt32(), quint32(123));
1031 QCOMPARE(qscriptvalue_cast<quint32>(str), quint32(123));
1032
1033 QScriptValue str2 = QScriptValue("NaN");
1034 QCOMPARE(str2.toUInt32(), quint32(0));
1035 QCOMPARE(qscriptvalue_cast<quint32>(str2), quint32(0));
1036
1037 QScriptValue str3 = QScriptValue("Infinity");
1038 QCOMPARE(str3.toUInt32(), quint32(0));
1039 QCOMPARE(qscriptvalue_cast<quint32>(str3), quint32(0));
1040
1041 QScriptValue str3_2 = QScriptValue("-Infinity");
1042 QCOMPARE(str3_2.toUInt32(), quint32(0));
1043 QCOMPARE(qscriptvalue_cast<quint32>(str3_2), quint32(0));
1044
1045 QScriptValue str4 = QScriptValue("0.5");
1046 QCOMPARE(str4.toUInt32(), quint32(0));
1047 QCOMPARE(qscriptvalue_cast<quint32>(str4), quint32(0));
1048
1049 QScriptValue str5 = QScriptValue("123.5");
1050 QCOMPARE(str5.toUInt32(), quint32(123));
1051 QCOMPARE(qscriptvalue_cast<quint32>(str5), quint32(123));
1052
1053 QScriptValue str6 = QScriptValue("-456.5");
1054 QCOMPARE(str6.toUInt32(), quint32(-456));
1055 QCOMPARE(qscriptvalue_cast<quint32>(str6), quint32(-456));
1056 }
1057
1058 QScriptValue inv;
1059 QCOMPARE(inv.toUInt32(), quint32(0));
1060 QCOMPARE(qscriptvalue_cast<quint32>(inv), quint32(0));
1061}
1062
1063void tst_QScriptValue::toUInt16()
1064{
1065 QScriptEngine eng;
1066
1067 {
1068 QScriptValue zer0 = QScriptValue(&eng, 0.0);
1069 QCOMPARE(zer0.toUInt16(), quint16(0));
1070 QCOMPARE(qscriptvalue_cast<quint16>(zer0), quint16(0));
1071
1072 QScriptValue number = QScriptValue(&eng, 123.0);
1073 QCOMPARE(number.toUInt16(), quint16(123));
1074 QCOMPARE(qscriptvalue_cast<quint16>(number), quint16(123));
1075
1076 QScriptValue number2 = QScriptValue(&eng, qSNaN());
1077 QCOMPARE(number2.toUInt16(), quint16(0));
1078 QCOMPARE(qscriptvalue_cast<quint16>(number2), quint16(0));
1079
1080 QScriptValue number3 = QScriptValue(&eng, +qInf());
1081 QCOMPARE(number3.toUInt16(), quint16(0));
1082 QCOMPARE(qscriptvalue_cast<quint16>(number3), quint16(0));
1083
1084 QScriptValue number3_2 = QScriptValue(&eng, -qInf());
1085 QCOMPARE(number3_2.toUInt16(), quint16(0));
1086 QCOMPARE(qscriptvalue_cast<quint16>(number3_2), quint16(0));
1087
1088 QScriptValue number4 = QScriptValue(&eng, 0.5);
1089 QCOMPARE(number4.toUInt16(), quint16(0));
1090
1091 QScriptValue number5 = QScriptValue(&eng, 123.5);
1092 QCOMPARE(number5.toUInt16(), quint16(123));
1093
1094 QScriptValue number6 = QScriptValue(&eng, -456.5);
1095 QCOMPARE(number6.toUInt16(), quint16(-456));
1096 QCOMPARE(qscriptvalue_cast<quint16>(number6), quint16(-456));
1097
1098 QScriptValue number7 = QScriptValue(&eng, 0x10000);
1099 QCOMPARE(number7.toUInt16(), quint16(0));
1100 QCOMPARE(qscriptvalue_cast<quint16>(number7), quint16(0));
1101
1102 QScriptValue number8 = QScriptValue(&eng, 0x10001);
1103 QCOMPARE(number8.toUInt16(), quint16(1));
1104 QCOMPARE(qscriptvalue_cast<quint16>(number8), quint16(1));
1105
1106 QScriptValue str = QScriptValue(&eng, "123.0");
1107 QCOMPARE(str.toUInt16(), quint16(123));
1108 QCOMPARE(qscriptvalue_cast<quint16>(str), quint16(123));
1109
1110 QScriptValue str2 = QScriptValue(&eng, "NaN");
1111 QCOMPARE(str2.toUInt16(), quint16(0));
1112 QCOMPARE(qscriptvalue_cast<quint16>(str2), quint16(0));
1113
1114 QScriptValue str3 = QScriptValue(&eng, "Infinity");
1115 QCOMPARE(str3.toUInt16(), quint16(0));
1116 QCOMPARE(qscriptvalue_cast<quint16>(str3), quint16(0));
1117
1118 QScriptValue str3_2 = QScriptValue(&eng, "-Infinity");
1119 QCOMPARE(str3_2.toUInt16(), quint16(0));
1120 QCOMPARE(qscriptvalue_cast<quint16>(str3_2), quint16(0));
1121
1122 QScriptValue str4 = QScriptValue(&eng, "0.5");
1123 QCOMPARE(str4.toUInt16(), quint16(0));
1124
1125 QScriptValue str5 = QScriptValue(&eng, "123.5");
1126 QCOMPARE(str5.toUInt16(), quint16(123));
1127
1128 QScriptValue str6 = QScriptValue(&eng, "-456.5");
1129 QCOMPARE(str6.toUInt16(), quint16(-456));
1130 QCOMPARE(qscriptvalue_cast<quint16>(str6), quint16(-456));
1131
1132 QScriptValue str7 = QScriptValue(&eng, "0x10000");
1133 QCOMPARE(str7.toUInt16(), quint16(0));
1134 QCOMPARE(qscriptvalue_cast<quint16>(str7), quint16(0));
1135
1136 QScriptValue str8 = QScriptValue(&eng, "0x10001");
1137 QCOMPARE(str8.toUInt16(), quint16(1));
1138 QCOMPARE(qscriptvalue_cast<quint16>(str8), quint16(1));
1139 }
1140 // V2 constructors
1141 {
1142 QScriptValue zer0 = QScriptValue(0.0);
1143 QCOMPARE(zer0.toUInt16(), quint16(0));
1144 QCOMPARE(qscriptvalue_cast<quint16>(zer0), quint16(0));
1145
1146 QScriptValue number = QScriptValue(123.0);
1147 QCOMPARE(number.toUInt16(), quint16(123));
1148 QCOMPARE(qscriptvalue_cast<quint16>(number), quint16(123));
1149
1150 QScriptValue number2 = QScriptValue(qSNaN());
1151 QCOMPARE(number2.toUInt16(), quint16(0));
1152 QCOMPARE(qscriptvalue_cast<quint16>(number2), quint16(0));
1153
1154 QScriptValue number3 = QScriptValue(+qInf());
1155 QCOMPARE(number3.toUInt16(), quint16(0));
1156 QCOMPARE(qscriptvalue_cast<quint16>(number3), quint16(0));
1157
1158 QScriptValue number3_2 = QScriptValue(-qInf());
1159 QCOMPARE(number3_2.toUInt16(), quint16(0));
1160 QCOMPARE(qscriptvalue_cast<quint16>(number3_2), quint16(0));
1161
1162 QScriptValue number4 = QScriptValue(0.5);
1163 QCOMPARE(number4.toUInt16(), quint16(0));
1164
1165 QScriptValue number5 = QScriptValue(123.5);
1166 QCOMPARE(number5.toUInt16(), quint16(123));
1167
1168 QScriptValue number6 = QScriptValue(-456.5);
1169 QCOMPARE(number6.toUInt16(), quint16(-456));
1170 QCOMPARE(qscriptvalue_cast<quint16>(number6), quint16(-456));
1171
1172 QScriptValue number7 = QScriptValue(0x10000);
1173 QCOMPARE(number7.toUInt16(), quint16(0));
1174 QCOMPARE(qscriptvalue_cast<quint16>(number7), quint16(0));
1175
1176 QScriptValue number8 = QScriptValue(0x10001);
1177 QCOMPARE(number8.toUInt16(), quint16(1));
1178 QCOMPARE(qscriptvalue_cast<quint16>(number8), quint16(1));
1179
1180 QScriptValue str = QScriptValue("123.0");
1181 QCOMPARE(str.toUInt16(), quint16(123));
1182 QCOMPARE(qscriptvalue_cast<quint16>(str), quint16(123));
1183
1184 QScriptValue str2 = QScriptValue("NaN");
1185 QCOMPARE(str2.toUInt16(), quint16(0));
1186 QCOMPARE(qscriptvalue_cast<quint16>(str2), quint16(0));
1187
1188 QScriptValue str3 = QScriptValue("Infinity");
1189 QCOMPARE(str3.toUInt16(), quint16(0));
1190 QCOMPARE(qscriptvalue_cast<quint16>(str3), quint16(0));
1191
1192 QScriptValue str3_2 = QScriptValue("-Infinity");
1193 QCOMPARE(str3_2.toUInt16(), quint16(0));
1194 QCOMPARE(qscriptvalue_cast<quint16>(str3_2), quint16(0));
1195
1196 QScriptValue str4 = QScriptValue("0.5");
1197 QCOMPARE(str4.toUInt16(), quint16(0));
1198
1199 QScriptValue str5 = QScriptValue("123.5");
1200 QCOMPARE(str5.toUInt16(), quint16(123));
1201
1202 QScriptValue str6 = QScriptValue("-456.5");
1203 QCOMPARE(str6.toUInt16(), quint16(-456));
1204 QCOMPARE(qscriptvalue_cast<quint16>(str6), quint16(-456));
1205
1206 QScriptValue str7 = QScriptValue("0x10000");
1207 QCOMPARE(str7.toUInt16(), quint16(0));
1208 QCOMPARE(qscriptvalue_cast<quint16>(str7), quint16(0));
1209
1210 QScriptValue str8 = QScriptValue("0x10001");
1211 QCOMPARE(str8.toUInt16(), quint16(1));
1212 QCOMPARE(qscriptvalue_cast<quint16>(str8), quint16(1));
1213 }
1214
1215 QScriptValue inv;
1216 QCOMPARE(inv.toUInt16(), quint16(0));
1217 QCOMPARE(qscriptvalue_cast<quint16>(inv), quint16(0));
1218}
1219
1220#if defined Q_CC_MSVC && _MSC_VER < 1300
1221Q_DECLARE_METATYPE(QVariant)
1222#endif
1223
1224void tst_QScriptValue::toVariant()
1225{
1226 QScriptEngine eng;
1227
1228 QScriptValue undefined = eng.undefinedValue();
1229 QCOMPARE(undefined.toVariant(), QVariant());
1230 QCOMPARE(qscriptvalue_cast<QVariant>(undefined), QVariant());
1231
1232 QScriptValue null = eng.nullValue();
1233 QCOMPARE(null.toVariant(), QVariant());
1234 QCOMPARE(qscriptvalue_cast<QVariant>(null), QVariant());
1235
1236 {
1237 QScriptValue number = QScriptValue(&eng, 123.0);
1238 QCOMPARE(number.toVariant(), QVariant(123.0));
1239 QCOMPARE(qscriptvalue_cast<QVariant>(number), QVariant(123.0));
1240
1241 QScriptValue intNumber = QScriptValue(&eng, (qint32)123);
1242 QCOMPARE(intNumber.toVariant().type(), QVariant((qint32)123).type());
1243 QCOMPARE((qscriptvalue_cast<QVariant>(number)).type(), QVariant((qint32)123).type());
1244
1245 QScriptValue falskt = QScriptValue(&eng, false);
1246 QCOMPARE(falskt.toVariant(), QVariant(false));
1247 QCOMPARE(qscriptvalue_cast<QVariant>(falskt), QVariant(false));
1248
1249 QScriptValue sant = QScriptValue(&eng, true);
1250 QCOMPARE(sant.toVariant(), QVariant(true));
1251 QCOMPARE(qscriptvalue_cast<QVariant>(sant), QVariant(true));
1252
1253 QScriptValue str = QScriptValue(&eng, QString("ciao"));
1254 QCOMPARE(str.toVariant(), QVariant(QString("ciao")));
1255 QCOMPARE(qscriptvalue_cast<QVariant>(str), QVariant(QString("ciao")));
1256 }
1257
1258 QVariant var(QChar(0x007A));
1259 QScriptValue opaque = eng.newVariant(value: var);
1260 QVERIFY(opaque.isVariant());
1261 QCOMPARE(opaque.toVariant(), var);
1262
1263 QScriptValue object = eng.newObject();
1264 QCOMPARE(object.toVariant(), QVariant(QVariantMap()));
1265
1266 QScriptValue qobject = eng.newQObject(object: this);
1267 {
1268 QVariant var = qobject.toVariant();
1269 QCOMPARE(var.userType(), int(QMetaType::QObjectStar));
1270 QCOMPARE(qvariant_cast<QObject*>(var), (QObject *)this);
1271 }
1272
1273 {
1274 QDateTime dateTime = QDateTime(QDate(1980, 10, 4));
1275 QScriptValue dateObject = eng.newDate(value: dateTime);
1276 QVariant var = dateObject.toVariant();
1277 QCOMPARE(var, QVariant(dateTime));
1278 }
1279
1280 {
1281 QRegExp rx = QRegExp("[0-9a-z]+", Qt::CaseSensitive, QRegExp::RegExp2);
1282 QScriptValue rxObject = eng.newRegExp(regexp: rx);
1283 QVariant var = rxObject.toVariant();
1284 QCOMPARE(var, QVariant(rx));
1285 }
1286
1287 QScriptValue inv;
1288 QCOMPARE(inv.toVariant(), QVariant());
1289 QCOMPARE(qscriptvalue_cast<QVariant>(inv), QVariant());
1290
1291 // V2 constructors
1292 {
1293 QScriptValue number = QScriptValue(123.0);
1294 QCOMPARE(number.toVariant(), QVariant(123.0));
1295 QCOMPARE(qscriptvalue_cast<QVariant>(number), QVariant(123.0));
1296
1297 QScriptValue falskt = QScriptValue(false);
1298 QCOMPARE(falskt.toVariant(), QVariant(false));
1299 QCOMPARE(qscriptvalue_cast<QVariant>(falskt), QVariant(false));
1300
1301 QScriptValue sant = QScriptValue(true);
1302 QCOMPARE(sant.toVariant(), QVariant(true));
1303 QCOMPARE(qscriptvalue_cast<QVariant>(sant), QVariant(true));
1304
1305 QScriptValue str = QScriptValue(QString("ciao"));
1306 QCOMPARE(str.toVariant(), QVariant(QString("ciao")));
1307 QCOMPARE(qscriptvalue_cast<QVariant>(str), QVariant(QString("ciao")));
1308 }
1309
1310 // array
1311 {
1312 QVariantList listIn;
1313 listIn << 123 << "hello";
1314 QScriptValue array = qScriptValueFromValue(engine: &eng, t: listIn);
1315 QVERIFY(array.isArray());
1316 QCOMPARE(array.property("length").toInt32(), 2);
1317 QVariant ret = array.toVariant();
1318 QCOMPARE(ret.type(), QVariant::List);
1319 QVariantList listOut = ret.toList();
1320 QCOMPARE(listOut.size(), listIn.size());
1321 for (int i = 0; i < listIn.size(); ++i)
1322 QVERIFY(listOut.at(i) == listIn.at(i));
1323 // round-trip conversion
1324 QScriptValue array2 = qScriptValueFromValue(engine: &eng, v: ret);
1325 QVERIFY(array2.isArray());
1326 QCOMPARE(array2.property("length").toInt32(), array.property("length").toInt32());
1327 for (int i = 0; i < array.property(name: "length").toInt32(); ++i)
1328 QVERIFY(array2.property(i).strictlyEquals(array.property(i)));
1329 }
1330}
1331
1332void tst_QScriptValue::toQObject_nonQObject_data()
1333{
1334 newEngine();
1335 QTest::addColumn<QScriptValue>(name: "value");
1336
1337 QTest::newRow(dataTag: "invalid") << QScriptValue();
1338 QTest::newRow(dataTag: "bool(false)") << QScriptValue(false);
1339 QTest::newRow(dataTag: "bool(true)") << QScriptValue(true);
1340 QTest::newRow(dataTag: "int") << QScriptValue(123);
1341 QTest::newRow(dataTag: "string") << QScriptValue(QString::fromLatin1(str: "ciao"));
1342 QTest::newRow(dataTag: "undefined") << QScriptValue(QScriptValue::UndefinedValue);
1343 QTest::newRow(dataTag: "null") << QScriptValue(QScriptValue::NullValue);
1344
1345 QTest::newRow(dataTag: "bool bound(false)") << QScriptValue(engine, false);
1346 QTest::newRow(dataTag: "bool bound(true)") << QScriptValue(engine, true);
1347 QTest::newRow(dataTag: "int bound") << QScriptValue(engine, 123);
1348 QTest::newRow(dataTag: "string bound") << QScriptValue(engine, QString::fromLatin1(str: "ciao"));
1349 QTest::newRow(dataTag: "undefined bound") << engine->undefinedValue();
1350 QTest::newRow(dataTag: "null bound") << engine->nullValue();
1351 QTest::newRow(dataTag: "object") << engine->newObject();
1352 QTest::newRow(dataTag: "array") << engine->newArray();
1353 QTest::newRow(dataTag: "date") << engine->newDate(value: 124);
1354 QTest::newRow(dataTag: "variant(12345)") << engine->newVariant(value: 12345);
1355 QTest::newRow(dataTag: "variant((QObject*)0)") << engine->newVariant(value: QVariant::fromValue(value: (QObject*)0));
1356 QTest::newRow(dataTag: "newQObject(0)") << engine->newQObject(object: 0);
1357}
1358
1359
1360void tst_QScriptValue::toQObject_nonQObject()
1361{
1362 QFETCH(QScriptValue, value);
1363 QCOMPARE(value.toQObject(), (QObject *)0);
1364 QCOMPARE(qscriptvalue_cast<QObject*>(value), (QObject *)0);
1365}
1366
1367// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
1368Q_DECLARE_METATYPE(QPushButton*);
1369
1370void tst_QScriptValue::toQObject()
1371{
1372 QScriptEngine eng;
1373
1374 QScriptValue qobject = eng.newQObject(object: this);
1375 QCOMPARE(qobject.toQObject(), (QObject *)this);
1376 QCOMPARE(qscriptvalue_cast<QObject*>(qobject), (QObject *)this);
1377 QCOMPARE(qscriptvalue_cast<QWidget*>(qobject), (QWidget *)0);
1378
1379 QWidget widget;
1380 QScriptValue qwidget = eng.newQObject(object: &widget);
1381 QCOMPARE(qwidget.toQObject(), (QObject *)&widget);
1382 QCOMPARE(qscriptvalue_cast<QObject*>(qwidget), (QObject *)&widget);
1383 QCOMPARE(qscriptvalue_cast<QWidget*>(qwidget), &widget);
1384
1385 QPushButton button;
1386 QScriptValue qbutton = eng.newQObject(object: &button);
1387 QCOMPARE(qbutton.toQObject(), (QObject *)&button);
1388 QCOMPARE(qscriptvalue_cast<QObject*>(qbutton), (QObject *)&button);
1389 QCOMPARE(qscriptvalue_cast<QWidget*>(qbutton), (QWidget *)&button);
1390 QCOMPARE(qscriptvalue_cast<QPushButton*>(qbutton), &button);
1391
1392 // wrapping a QObject* as variant
1393 QScriptValue variant = eng.newVariant(value: QVariant::fromValue(value: (QObject*)&button));
1394 QCOMPARE(variant.toQObject(), (QObject*)&button);
1395 QCOMPARE(qscriptvalue_cast<QObject*>(variant), (QObject*)&button);
1396 QCOMPARE(qscriptvalue_cast<QWidget*>(variant), (QWidget*)&button);
1397 QCOMPARE(qscriptvalue_cast<QPushButton*>(variant), &button);
1398
1399 QScriptValue variant2 = eng.newVariant(value: QVariant::fromValue(value: (QWidget*)&button));
1400 QCOMPARE(variant2.toQObject(), (QObject*)&button);
1401 QCOMPARE(qscriptvalue_cast<QObject*>(variant2), (QObject*)&button);
1402 QCOMPARE(qscriptvalue_cast<QWidget*>(variant2), (QWidget*)&button);
1403 QCOMPARE(qscriptvalue_cast<QPushButton*>(variant2), &button);
1404
1405 QScriptValue variant3 = eng.newVariant(value: QVariant::fromValue(value: &button));
1406 QVERIFY(variant3.isQObject());
1407 QCOMPARE(variant3.toQObject(), (QObject*)&button);
1408 QCOMPARE(qscriptvalue_cast<QObject*>(variant3), (QObject*)&button);
1409 QCOMPARE(qscriptvalue_cast<QWidget*>(variant3), (QWidget*)&button);
1410 QCOMPARE(qscriptvalue_cast<QPushButton*>(variant3), &button);
1411}
1412
1413void tst_QScriptValue::toObject()
1414{
1415 QScriptEngine eng;
1416
1417 QScriptValue undefined = eng.undefinedValue();
1418 QCOMPARE(undefined.toObject().isValid(), false);
1419 QVERIFY(undefined.isUndefined());
1420
1421 QScriptValue null = eng.nullValue();
1422 QCOMPARE(null.toObject().isValid(), false);
1423 QVERIFY(null.isNull());
1424
1425 {
1426 QScriptValue falskt = QScriptValue(&eng, false);
1427 {
1428 QScriptValue tmp = falskt.toObject();
1429 QCOMPARE(tmp.isObject(), true);
1430 QCOMPARE(tmp.toNumber(), falskt.toNumber());
1431 }
1432 QVERIFY(falskt.isBool());
1433
1434 QScriptValue sant = QScriptValue(&eng, true);
1435 {
1436 QScriptValue tmp = sant.toObject();
1437 QCOMPARE(tmp.isObject(), true);
1438 QCOMPARE(tmp.toNumber(), sant.toNumber());
1439 }
1440 QVERIFY(sant.isBool());
1441
1442 QScriptValue number = QScriptValue(&eng, 123.0);
1443 {
1444 QScriptValue tmp = number.toObject();
1445 QCOMPARE(tmp.isObject(), true);
1446 QCOMPARE(tmp.toNumber(), number.toNumber());
1447 }
1448 QVERIFY(number.isNumber());
1449
1450 QScriptValue str = QScriptValue(&eng, QString("ciao"));
1451 {
1452 QScriptValue tmp = str.toObject();
1453 QCOMPARE(tmp.isObject(), true);
1454 QCOMPARE(tmp.toString(), str.toString());
1455 }
1456 QVERIFY(str.isString());
1457 }
1458
1459 QScriptValue object = eng.newObject();
1460 {
1461 QScriptValue tmp = object.toObject();
1462 QCOMPARE(tmp.isObject(), true);
1463 }
1464
1465 QScriptValue qobject = eng.newQObject(object: this);
1466 QCOMPARE(qobject.toObject().isValid(), true);
1467
1468 QScriptValue inv;
1469 QCOMPARE(inv.toObject().isValid(), false);
1470
1471 // V2 constructors: in this case, you have to use QScriptEngine::toObject()
1472 {
1473 QScriptValue undefined = QScriptValue(QScriptValue::UndefinedValue);
1474 QVERIFY(!undefined.toObject().isValid());
1475 QVERIFY(!eng.toObject(undefined).isValid());
1476 QVERIFY(undefined.isUndefined());
1477
1478 QScriptValue null = QScriptValue(QScriptValue::NullValue);
1479 QVERIFY(!null.toObject().isValid());
1480 QVERIFY(!eng.toObject(null).isValid());
1481 QVERIFY(null.isNull());
1482
1483 QScriptValue falskt = QScriptValue(false);
1484 QVERIFY(!falskt.toObject().isValid());
1485 {
1486 QScriptValue tmp = eng.toObject(value: falskt);
1487 QVERIFY(tmp.isObject());
1488 QVERIFY(tmp.toBool());
1489 }
1490 QVERIFY(falskt.isBool());
1491
1492 QScriptValue sant = QScriptValue(true);
1493 QVERIFY(!sant.toObject().isValid());
1494 {
1495 QScriptValue tmp = eng.toObject(value: sant);
1496 QVERIFY(tmp.isObject());
1497 QVERIFY(tmp.toBool());
1498 }
1499 QVERIFY(sant.isBool());
1500
1501 QScriptValue number = QScriptValue(123.0);
1502 QVERIFY(!number.toObject().isValid());
1503 {
1504 QScriptValue tmp = eng.toObject(value: number);
1505 QVERIFY(tmp.isObject());
1506 QCOMPARE(tmp.toInt32(), number.toInt32());
1507 }
1508 QVERIFY(number.isNumber());
1509
1510 QScriptValue str = QScriptValue(QString::fromLatin1(str: "ciao"));
1511 QVERIFY(!str.toObject().isValid());
1512 {
1513 QScriptValue tmp = eng.toObject(value: str);
1514 QVERIFY(tmp.isObject());
1515 QCOMPARE(tmp.toString(), QString::fromLatin1("ciao"));
1516 }
1517 QVERIFY(str.isString());
1518 }
1519}
1520
1521void tst_QScriptValue::toDateTime()
1522{
1523 QScriptEngine eng;
1524 QDateTime dt = eng.evaluate(program: "new Date(0)").toDateTime();
1525 QVERIFY(dt.isValid());
1526 QCOMPARE(dt.timeSpec(), Qt::LocalTime);
1527 QCOMPARE(dt.toUTC(), QDateTime::fromMSecsSinceEpoch(0, Qt::UTC));
1528
1529 QVERIFY(!eng.evaluate("[]").toDateTime().isValid());
1530 QVERIFY(!eng.evaluate("{}").toDateTime().isValid());
1531 QVERIFY(!eng.globalObject().toDateTime().isValid());
1532 QVERIFY(!QScriptValue().toDateTime().isValid());
1533 QVERIFY(!QScriptValue(123).toDateTime().isValid());
1534 QVERIFY(!QScriptValue(false).toDateTime().isValid());
1535 QVERIFY(!eng.nullValue().toDateTime().isValid());
1536 QVERIFY(!eng.undefinedValue().toDateTime().isValid());
1537}
1538
1539void tst_QScriptValue::toRegExp()
1540{
1541 QScriptEngine eng;
1542 {
1543 QRegExp rx = eng.evaluate(program: "/foo/").toRegExp();
1544 QVERIFY(rx.isValid());
1545 QCOMPARE(rx.patternSyntax(), QRegExp::RegExp2);
1546 QCOMPARE(rx.pattern(), QString::fromLatin1("foo"));
1547 QCOMPARE(rx.caseSensitivity(), Qt::CaseSensitive);
1548 QVERIFY(!rx.isMinimal());
1549 }
1550 {
1551 QRegExp rx = eng.evaluate(program: "/bar/gi").toRegExp();
1552 QVERIFY(rx.isValid());
1553 QCOMPARE(rx.patternSyntax(), QRegExp::RegExp2);
1554 QCOMPARE(rx.pattern(), QString::fromLatin1("bar"));
1555 QCOMPARE(rx.caseSensitivity(), Qt::CaseInsensitive);
1556 QVERIFY(!rx.isMinimal());
1557 }
1558
1559 QVERIFY(eng.evaluate("[]").toRegExp().isEmpty());
1560 QVERIFY(eng.evaluate("{}").toRegExp().isEmpty());
1561 QVERIFY(eng.globalObject().toRegExp().isEmpty());
1562 QVERIFY(QScriptValue().toRegExp().isEmpty());
1563 QVERIFY(QScriptValue(123).toRegExp().isEmpty());
1564 QVERIFY(QScriptValue(false).toRegExp().isEmpty());
1565 QVERIFY(eng.nullValue().toRegExp().isEmpty());
1566 QVERIFY(eng.undefinedValue().toRegExp().isEmpty());
1567}
1568
1569void tst_QScriptValue::instanceOf_twoEngines()
1570{
1571 QScriptEngine eng;
1572 QScriptValue obj = eng.newObject();
1573 QScriptEngine otherEngine;
1574 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::instanceof: cannot perform operation on a value created in a different engine");
1575 QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false);
1576}
1577
1578void tst_QScriptValue::instanceOf()
1579{
1580 QScriptEngine eng;
1581 QScriptValue obj = eng.newObject();
1582 QCOMPARE(obj.instanceOf(eng.evaluate("Object.prototype")), false);
1583 QCOMPARE(obj.instanceOf(eng.evaluate("Array.prototype")), false);
1584 QCOMPARE(obj.instanceOf(eng.evaluate("Function.prototype")), false);
1585 QCOMPARE(obj.instanceOf(eng.evaluate("QObject.prototype")), false);
1586 QCOMPARE(obj.instanceOf(QScriptValue(&eng, 123)), false);
1587 QCOMPARE(obj.instanceOf(eng.undefinedValue()), false);
1588 QCOMPARE(obj.instanceOf(eng.nullValue()), false);
1589 QCOMPARE(obj.instanceOf(QScriptValue()), false);
1590
1591 QCOMPARE(obj.instanceOf(eng.evaluate("Object")), true);
1592 QCOMPARE(obj.instanceOf(eng.evaluate("Array")), false);
1593 QCOMPARE(obj.instanceOf(eng.evaluate("Function")), false);
1594 QCOMPARE(obj.instanceOf(eng.evaluate("QObject")), false);
1595
1596 QScriptValue arr = eng.newArray();
1597 QVERIFY(arr.isArray());
1598 QCOMPARE(arr.instanceOf(eng.evaluate("Object.prototype")), false);
1599 QCOMPARE(arr.instanceOf(eng.evaluate("Array.prototype")), false);
1600 QCOMPARE(arr.instanceOf(eng.evaluate("Function.prototype")), false);
1601 QCOMPARE(arr.instanceOf(eng.evaluate("QObject.prototype")), false);
1602 QCOMPARE(arr.instanceOf(eng.evaluate("Object")), true);
1603 QCOMPARE(arr.instanceOf(eng.evaluate("Array")), true);
1604 QCOMPARE(arr.instanceOf(eng.evaluate("Function")), false);
1605 QCOMPARE(arr.instanceOf(eng.evaluate("QObject")), false);
1606
1607 QCOMPARE(QScriptValue().instanceOf(arr), false);
1608}
1609
1610void tst_QScriptValue::isArray_data()
1611{
1612 newEngine();
1613
1614 QTest::addColumn<QScriptValue>(name: "value");
1615 QTest::addColumn<bool>(name: "array");
1616
1617 QTest::newRow(dataTag: "[]") << engine->evaluate(program: "[]") << true;
1618 QTest::newRow(dataTag: "{}") << engine->evaluate(program: "{}") << false;
1619 QTest::newRow(dataTag: "globalObject") << engine->globalObject() << false;
1620 QTest::newRow(dataTag: "invalid") << QScriptValue() << false;
1621 QTest::newRow(dataTag: "number") << QScriptValue(123) << false;
1622 QTest::newRow(dataTag: "bool") << QScriptValue(false) << false;
1623 QTest::newRow(dataTag: "null") << engine->nullValue() << false;
1624 QTest::newRow(dataTag: "undefined") << engine->undefinedValue() << false;
1625}
1626
1627void tst_QScriptValue::isArray()
1628{
1629 QFETCH(QScriptValue, value);
1630 QFETCH(bool, array);
1631
1632 QCOMPARE(value.isArray(), array);
1633}
1634
1635void tst_QScriptValue::isDate_data()
1636{
1637 newEngine();
1638
1639 QTest::addColumn<QScriptValue>(name: "value");
1640 QTest::addColumn<bool>(name: "date");
1641
1642 QTest::newRow(dataTag: "date") << engine->evaluate(program: "new Date()") << true;
1643 QTest::newRow(dataTag: "[]") << engine->evaluate(program: "[]") << false;
1644 QTest::newRow(dataTag: "{}") << engine->evaluate(program: "{}") << false;
1645 QTest::newRow(dataTag: "globalObject") << engine->globalObject() << false;
1646 QTest::newRow(dataTag: "invalid") << QScriptValue() << false;
1647 QTest::newRow(dataTag: "number") << QScriptValue(123) << false;
1648 QTest::newRow(dataTag: "bool") << QScriptValue(false) << false;
1649 QTest::newRow(dataTag: "null") << engine->nullValue() << false;
1650 QTest::newRow(dataTag: "undefined") << engine->undefinedValue() << false;
1651}
1652
1653void tst_QScriptValue::isDate()
1654{
1655 QFETCH(QScriptValue, value);
1656 QFETCH(bool, date);
1657
1658 QCOMPARE(value.isDate(), date);
1659}
1660
1661void tst_QScriptValue::isError_propertiesOfGlobalObject()
1662{
1663 QStringList errors;
1664 errors << "Error"
1665 << "EvalError"
1666 << "RangeError"
1667 << "ReferenceError"
1668 << "SyntaxError"
1669 << "TypeError"
1670 << "URIError";
1671 QScriptEngine eng;
1672 for (int i = 0; i < errors.size(); ++i) {
1673 QScriptValue ctor = eng.globalObject().property(name: errors.at(i));
1674 QVERIFY(ctor.isFunction());
1675 QVERIFY(ctor.property("prototype").isError());
1676 }
1677}
1678
1679void tst_QScriptValue::isError_data()
1680{
1681 newEngine();
1682
1683 QTest::addColumn<QScriptValue>(name: "value");
1684 QTest::addColumn<bool>(name: "error");
1685
1686 QTest::newRow(dataTag: "syntax error") << engine->evaluate(program: "%fsdg's") << true;
1687 QTest::newRow(dataTag: "[]") << engine->evaluate(program: "[]") << false;
1688 QTest::newRow(dataTag: "{}") << engine->evaluate(program: "{}") << false;
1689 QTest::newRow(dataTag: "globalObject") << engine->globalObject() << false;
1690 QTest::newRow(dataTag: "invalid") << QScriptValue() << false;
1691 QTest::newRow(dataTag: "number") << QScriptValue(123) << false;
1692 QTest::newRow(dataTag: "bool") << QScriptValue(false) << false;
1693 QTest::newRow(dataTag: "null") << engine->nullValue() << false;
1694 QTest::newRow(dataTag: "undefined") << engine->undefinedValue() << false;
1695 QTest::newRow(dataTag: "newObject") << engine->newObject() << false;
1696 QTest::newRow(dataTag: "new Object") << engine->evaluate(program: "new Object()") << false;
1697}
1698
1699void tst_QScriptValue::isError()
1700{
1701 QFETCH(QScriptValue, value);
1702 QFETCH(bool, error);
1703
1704 QCOMPARE(value.isError(), error);
1705}
1706
1707void tst_QScriptValue::isRegExp_data()
1708{
1709 newEngine();
1710
1711 QTest::addColumn<QScriptValue>(name: "value");
1712 QTest::addColumn<bool>(name: "regexp");
1713
1714 QTest::newRow(dataTag: "/foo/") << engine->evaluate(program: "/foo/") << true;
1715 QTest::newRow(dataTag: "[]") << engine->evaluate(program: "[]") << false;
1716 QTest::newRow(dataTag: "{}") << engine->evaluate(program: "{}") << false;
1717 QTest::newRow(dataTag: "globalObject") << engine->globalObject() << false;
1718 QTest::newRow(dataTag: "invalid") << QScriptValue() << false;
1719 QTest::newRow(dataTag: "number") << QScriptValue(123) << false;
1720 QTest::newRow(dataTag: "bool") << QScriptValue(false) << false;
1721 QTest::newRow(dataTag: "null") << engine->nullValue() << false;
1722 QTest::newRow(dataTag: "undefined") << engine->undefinedValue() << false;
1723}
1724
1725void tst_QScriptValue::isRegExp()
1726{
1727 QFETCH(QScriptValue, value);
1728 QFETCH(bool, regexp);
1729
1730 QCOMPARE(value.isRegExp(), regexp);
1731}
1732
1733static QScriptValue getter(QScriptContext *ctx, QScriptEngine *)
1734{
1735 return ctx->thisObject().property(name: "x");
1736}
1737
1738static QScriptValue setter(QScriptContext *ctx, QScriptEngine *)
1739{
1740 ctx->thisObject().setProperty(name: "x", value: ctx->argument(index: 0));
1741 return ctx->argument(index: 0);
1742}
1743
1744static QScriptValue getterSetter(QScriptContext *ctx, QScriptEngine *)
1745{
1746 if (ctx->argumentCount() > 0)
1747 ctx->thisObject().setProperty(name: "x", value: ctx->argument(index: 0));
1748 return ctx->thisObject().property(name: "x");
1749}
1750
1751static QScriptValue getterSetterThrowingError(QScriptContext *ctx, QScriptEngine *)
1752{
1753 if (ctx->argumentCount() > 0)
1754 return ctx->throwError(text: "set foo");
1755 else
1756 return ctx->throwError(text: "get foo");
1757}
1758
1759static QScriptValue getSet__proto__(QScriptContext *ctx, QScriptEngine *)
1760{
1761 if (ctx->argumentCount() > 0)
1762 ctx->callee().setProperty(name: "value", value: ctx->argument(index: 0));
1763 return ctx->callee().property(name: "value");
1764}
1765
1766void tst_QScriptValue::getSetProperty_HooliganTask162051()
1767{
1768 QScriptEngine eng;
1769 // task 162051 -- detecting whether the property is an array index or not
1770 QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123)));
1771 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
1772 QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QScriptValue(&eng, true)));
1773 QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QScriptValue(&eng, false)));
1774 QVERIFY(eng.evaluate("a[0]").isUndefined());
1775 QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QScriptValue(&eng, 456)));
1776 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
1777 QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QScriptValue(&eng, true)));
1778 QVERIFY(eng.evaluate("a[0]").isUndefined());
1779 QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789)));
1780 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1)));
1781}
1782
1783void tst_QScriptValue::getSetProperty_HooliganTask183072()
1784{
1785 QScriptEngine eng;
1786 // task 183072 -- 0x800000000 is not an array index
1787 eng.evaluate(program: "a = []; a[0x800000000] = 123");
1788 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
1789 QVERIFY(eng.evaluate("a[0]").isUndefined());
1790 QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123)));
1791}
1792
1793void tst_QScriptValue::getSetProperty_propertyRemoval()
1794{
1795 // test property removal (setProperty(QScriptValue()))
1796 QScriptEngine eng;
1797 QScriptValue object = eng.newObject();
1798 QScriptValue str = QScriptValue(&eng, "bar");
1799 QScriptValue num = QScriptValue(&eng, 123.0);
1800
1801 object.setProperty(name: "foo", value: num);
1802 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1803 object.setProperty(name: "bar", value: str);
1804 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1805 object.setProperty(name: "foo", value: QScriptValue());
1806 QCOMPARE(object.property("foo").isValid(), false);
1807 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1808 object.setProperty(name: "foo", value: num);
1809 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1810 QCOMPARE(object.property("bar").strictlyEquals(str), true);
1811 object.setProperty(name: "bar", value: QScriptValue());
1812 QCOMPARE(object.property("bar").isValid(), false);
1813 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1814 object.setProperty(name: "foo", value: QScriptValue());
1815 object.setProperty(name: "foo", value: QScriptValue());
1816
1817 eng.globalObject().setProperty(name: "object3", value: object);
1818 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1819 .strictlyEquals(QScriptValue(&eng, false)), true);
1820 object.setProperty(name: "foo", value: num);
1821 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
1822 .strictlyEquals(QScriptValue(&eng, true)), true);
1823 eng.globalObject().setProperty(name: "object3", value: QScriptValue());
1824 QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')")
1825 .strictlyEquals(QScriptValue(&eng, false)), true);
1826}
1827
1828void tst_QScriptValue::getSetProperty_resolveMode()
1829{
1830 // test ResolveMode
1831 QScriptEngine eng;
1832 QScriptValue object = eng.newObject();
1833 QScriptValue prototype = eng.newObject();
1834 object.setPrototype(prototype);
1835 QScriptValue num2 = QScriptValue(&eng, 456.0);
1836 prototype.setProperty(name: "propertyInPrototype", value: num2);
1837 // default is ResolvePrototype
1838 QCOMPARE(object.property("propertyInPrototype")
1839 .strictlyEquals(num2), true);
1840 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolvePrototype)
1841 .strictlyEquals(num2), true);
1842 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveLocal)
1843 .isValid(), false);
1844 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveScope)
1845 .strictlyEquals(num2), false);
1846 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull)
1847 .strictlyEquals(num2), true);
1848}
1849
1850void tst_QScriptValue::getSetProperty_twoEngines()
1851{
1852 QScriptEngine engine;
1853 QScriptValue object = engine.newObject();
1854
1855 QScriptEngine otherEngine;
1856 QScriptValue otherNum = QScriptValue(&otherEngine, 123);
1857 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setProperty(oof) failed: cannot set value created in a different engine");
1858 object.setProperty(name: "oof", value: otherNum);
1859 QCOMPARE(object.property("oof").isValid(), false);
1860}
1861
1862
1863void tst_QScriptValue::getSetProperty_gettersAndSetters()
1864{
1865 QScriptEngine eng;
1866 QScriptValue str = QScriptValue(&eng, "bar");
1867 QScriptValue num = QScriptValue(&eng, 123.0);
1868 QScriptValue object = eng.newObject();
1869 for (int x = 0; x < 2; ++x) {
1870 object.setProperty(name: "foo", value: QScriptValue());
1871 // getter() returns this.x
1872 object.setProperty(name: "foo", value: eng.newFunction(signature: getter),
1873 flags: QScriptValue::PropertyGetter | QScriptValue::UserRange);
1874 QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange,
1875 QScriptValue::PropertyGetter );
1876
1877 QEXPECT_FAIL("", "QTBUG-17615: User-range flags are not retained for getter/setter properties", Continue);
1878 QCOMPARE(object.propertyFlags("foo"),
1879 QScriptValue::PropertyGetter | QScriptValue::UserRange);
1880 object.setProperty(name: "x", value: num);
1881 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1882
1883 // setter() sets this.x
1884 object.setProperty(name: "foo", value: eng.newFunction(signature: setter),
1885 flags: QScriptValue::PropertySetter);
1886 QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange,
1887 QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
1888
1889 QCOMPARE(object.propertyFlags("foo"),
1890 QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
1891 object.setProperty(name: "foo", value: str);
1892 QCOMPARE(object.property("x").strictlyEquals(str), true);
1893 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1894
1895 // kill the getter
1896 object.setProperty(name: "foo", value: QScriptValue(), flags: QScriptValue::PropertyGetter);
1897 QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertyGetter));
1898 QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter);
1899 QCOMPARE(object.property("foo").isUndefined(), true);
1900
1901 // setter should still work
1902 object.setProperty(name: "foo", value: num);
1903 QCOMPARE(object.property("x").strictlyEquals(num), true);
1904
1905 // kill the setter too
1906 object.setProperty(name: "foo", value: QScriptValue(), flags: QScriptValue::PropertySetter);
1907 QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertySetter));
1908 // now foo is just a regular property
1909 object.setProperty(name: "foo", value: str);
1910 QCOMPARE(object.property("x").strictlyEquals(num), true);
1911 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1912 }
1913
1914 for (int x = 0; x < 2; ++x) {
1915 object.setProperty(name: "foo", value: QScriptValue());
1916 // setter() sets this.x
1917 object.setProperty(name: "foo", value: eng.newFunction(signature: setter), flags: QScriptValue::PropertySetter);
1918 object.setProperty(name: "foo", value: str);
1919 QCOMPARE(object.property("x").strictlyEquals(str), true);
1920 QCOMPARE(object.property("foo").isUndefined(), true);
1921
1922 // getter() returns this.x
1923 object.setProperty(name: "foo", value: eng.newFunction(signature: getter), flags: QScriptValue::PropertyGetter);
1924 object.setProperty(name: "x", value: num);
1925 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1926
1927 // kill the setter
1928 object.setProperty(name: "foo", value: QScriptValue(), flags: QScriptValue::PropertySetter);
1929 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setProperty() failed: property 'foo' has a getter but no setter");
1930 object.setProperty(name: "foo", value: str);
1931
1932 // getter should still work
1933 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1934
1935 // kill the getter too
1936 object.setProperty(name: "foo", value: QScriptValue(), flags: QScriptValue::PropertyGetter);
1937 // now foo is just a regular property
1938 object.setProperty(name: "foo", value: str);
1939 QCOMPARE(object.property("x").strictlyEquals(num), true);
1940 QCOMPARE(object.property("foo").strictlyEquals(str), true);
1941 }
1942
1943 // use a single function as both getter and setter
1944 object.setProperty(name: "foo", value: QScriptValue());
1945 object.setProperty(name: "foo", value: eng.newFunction(signature: getterSetter),
1946 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
1947 QCOMPARE(object.propertyFlags("foo"),
1948 QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
1949 object.setProperty(name: "x", value: num);
1950 QCOMPARE(object.property("foo").strictlyEquals(num), true);
1951
1952 // killing the getter will preserve the setter, even though they are the same function
1953 object.setProperty(name: "foo", value: QScriptValue(), flags: QScriptValue::PropertyGetter);
1954 QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter);
1955 QCOMPARE(object.property("foo").isUndefined(), true);
1956}
1957
1958void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorNative()
1959{
1960 // getter/setter that throws an error
1961 QScriptEngine eng;
1962 QScriptValue str = QScriptValue(&eng, "bar");
1963 QScriptValue object = eng.newObject();
1964
1965 object.setProperty(name: "foo", value: eng.newFunction(signature: getterSetterThrowingError),
1966 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
1967 QVERIFY(!eng.hasUncaughtException());
1968 QScriptValue ret = object.property(name: "foo");
1969 QVERIFY(ret.isError());
1970 QVERIFY(eng.hasUncaughtException());
1971 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
1972 QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
1973 eng.evaluate(program: "Object"); // clear exception state...
1974 QVERIFY(!eng.hasUncaughtException());
1975 object.setProperty(name: "foo", value: str);
1976 QVERIFY(eng.hasUncaughtException());
1977 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
1978}
1979
1980void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorJS()
1981{
1982 // getter/setter that throws an error (from js function)
1983 QScriptEngine eng;
1984 QScriptValue str = QScriptValue(&eng, "bar");
1985
1986 eng.evaluate(program: "o = new Object; "
1987 "o.__defineGetter__('foo', function() { throw new Error('get foo') }); "
1988 "o.__defineSetter__('foo', function() { throw new Error('set foo') }); ");
1989 QScriptValue object = eng.evaluate(program: "o");
1990 QVERIFY(!eng.hasUncaughtException());
1991 QScriptValue ret = object.property(name: "foo");
1992 QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue);
1993 QVERIFY(ret.isError());
1994 QVERIFY(eng.hasUncaughtException());
1995 QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue);
1996 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
1997 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: get foo"));
1998 eng.evaluate(program: "Object"); // clear exception state...
1999 QVERIFY(!eng.hasUncaughtException());
2000 object.setProperty(name: "foo", value: str);
2001 QVERIFY(eng.hasUncaughtException());
2002 QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
2003}
2004
2005void tst_QScriptValue::getSetProperty_gettersAndSettersOnNative()
2006{
2007 // attempt to install getter+setter on built-in (native) property
2008 QScriptEngine eng;
2009 QScriptValue object = eng.newObject();
2010 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2011
2012 QScriptValue fun = eng.newFunction(signature: getSet__proto__);
2013 fun.setProperty(name: "value", value: QScriptValue(&eng, "boo"));
2014 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setProperty() failed: "
2015 "cannot set getter or setter of native property "
2016 "`__proto__'");
2017 object.setProperty(name: "__proto__", value: fun,
2018 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter
2019 | QScriptValue::UserRange);
2020 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2021
2022 object.setProperty(name: "__proto__", value: QScriptValue(),
2023 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
2024 QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
2025}
2026
2027void tst_QScriptValue::getSetProperty_gettersAndSettersOnGlobalObject()
2028{
2029 // global property that's a getter+setter
2030 QScriptEngine eng;
2031 eng.globalObject().setProperty(name: "globalGetterSetterProperty", value: eng.newFunction(signature: getterSetter),
2032 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
2033 eng.evaluate(program: "globalGetterSetterProperty = 123");
2034 {
2035 QScriptValue ret = eng.evaluate(program: "globalGetterSetterProperty");
2036 QVERIFY(ret.isNumber());
2037 QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 123)));
2038 }
2039 QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(),
2040 QString::fromLatin1("number"));
2041 {
2042 QScriptValue ret = eng.evaluate(program: "this.globalGetterSetterProperty()");
2043 QVERIFY(ret.isError());
2044 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a function."));
2045 }
2046 {
2047 QScriptValue ret = eng.evaluate(program: "new this.globalGetterSetterProperty()");
2048 QVERIFY(ret.isError());
2049 QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a constructor."));
2050 }
2051}
2052
2053void tst_QScriptValue::getSetProperty_gettersAndSettersChange()
2054{
2055 // "upgrading" an existing property to become a getter+setter
2056 QScriptEngine eng;
2057 QScriptValue object = eng.newObject();
2058 QScriptValue num(&eng, 123);
2059 object.setProperty(name: "foo", value: num);
2060 object.setProperty(name: "foo", value: eng.newFunction(signature: getterSetter),
2061 flags: QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
2062 QVERIFY(!object.property("x").isValid());
2063 object.setProperty(name: "foo", value: num);
2064 QVERIFY(object.property("x").equals(num));
2065
2066 eng.globalObject().setProperty(name: "object", value: object);
2067 QScriptValue res = eng.evaluate(program: "object.x = 89; var a = object.foo; object.foo = 65; a");
2068 QCOMPARE(res.toInt32(), 89);
2069 QCOMPARE(object.property("x").toInt32(), 65);
2070 QCOMPARE(object.property("foo").toInt32(), 65);
2071}
2072
2073void tst_QScriptValue::getSetProperty_array()
2074{
2075 QScriptEngine eng;
2076 QScriptValue str = QScriptValue(&eng, "bar");
2077 QScriptValue num = QScriptValue(&eng, 123.0);
2078 QScriptValue array = eng.newArray();
2079
2080 QVERIFY(array.isArray());
2081 array.setProperty(arrayIndex: 0, value: num);
2082 QCOMPARE(array.property(0).toNumber(), num.toNumber());
2083 QCOMPARE(array.property("0").toNumber(), num.toNumber());
2084 QCOMPARE(array.property("length").toUInt32(), quint32(1));
2085 array.setProperty(arrayIndex: 1, value: str);
2086 QCOMPARE(array.property(1).toString(), str.toString());
2087 QCOMPARE(array.property("1").toString(), str.toString());
2088 QCOMPARE(array.property("length").toUInt32(), quint32(2));
2089 array.setProperty(name: "length", value: QScriptValue(&eng, 1));
2090 QCOMPARE(array.property("length").toUInt32(), quint32(1));
2091 QCOMPARE(array.property(1).isValid(), false);
2092}
2093
2094void tst_QScriptValue::getSetProperty()
2095{
2096 QScriptEngine eng;
2097
2098 QScriptValue object = eng.newObject();
2099
2100 QScriptValue str = QScriptValue(&eng, "bar");
2101 object.setProperty(name: "foo", value: str);
2102 QCOMPARE(object.property("foo").toString(), str.toString());
2103
2104 QScriptValue num = QScriptValue(&eng, 123.0);
2105 object.setProperty(name: "baz", value: num);
2106 QCOMPARE(object.property("baz").toNumber(), num.toNumber());
2107
2108 QScriptValue strstr = QScriptValue("bar");
2109 QCOMPARE(strstr.engine(), (QScriptEngine *)0);
2110 object.setProperty(name: "foo", value: strstr);
2111 QCOMPARE(object.property("foo").toString(), strstr.toString());
2112 QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
2113
2114 QScriptValue numnum = QScriptValue(123.0);
2115 object.setProperty(name: "baz", value: numnum);
2116 QCOMPARE(object.property("baz").toNumber(), numnum.toNumber());
2117
2118 QScriptValue inv;
2119 inv.setProperty(name: "foo", value: num);
2120 QCOMPARE(inv.property("foo").isValid(), false);
2121
2122 eng.globalObject().setProperty(name: "object", value: object);
2123
2124 // ReadOnly
2125 object.setProperty(name: "readOnlyProperty", value: num, flags: QScriptValue::ReadOnly);
2126 QCOMPARE(object.propertyFlags("readOnlyProperty"), QScriptValue::ReadOnly);
2127 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2128 eng.evaluate(program: "object.readOnlyProperty = !object.readOnlyProperty");
2129 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
2130 // should still be part of enumeration
2131 {
2132 QScriptValue ret = eng.evaluate(
2133 program: "found = false;"
2134 "for (var p in object) {"
2135 " if (p == 'readOnlyProperty') {"
2136 " found = true; break;"
2137 " }"
2138 "} found");
2139 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
2140 }
2141 // should still be deletable
2142 {
2143 QScriptValue ret = eng.evaluate(program: "delete object.readOnlyProperty");
2144 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
2145 QCOMPARE(object.property("readOnlyProperty").isValid(), false);
2146 }
2147
2148 // Undeletable
2149 object.setProperty(name: "undeletableProperty", value: num, flags: QScriptValue::Undeletable);
2150 QCOMPARE(object.propertyFlags("undeletableProperty"), QScriptValue::Undeletable);
2151 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2152 {
2153 QScriptValue ret = eng.evaluate(program: "delete object.undeletableProperty");
2154 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), false);
2155 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
2156 }
2157 // should still be writable
2158 eng.evaluate(program: "object.undeletableProperty = object.undeletableProperty + 1");
2159 QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1);
2160 // should still be part of enumeration
2161 {
2162 QScriptValue ret = eng.evaluate(
2163 program: "found = false;"
2164 "for (var p in object) {"
2165 " if (p == 'undeletableProperty') {"
2166 " found = true; break;"
2167 " }"
2168 "} found");
2169 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
2170 }
2171 // should still be deletable from C++
2172 object.setProperty(name: "undeletableProperty", value: QScriptValue());
2173 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2174 QVERIFY(!object.property("undeletableProperty").isValid());
2175 QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
2176 QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
2177
2178 // SkipInEnumeration
2179 object.setProperty(name: "dontEnumProperty", value: num, flags: QScriptValue::SkipInEnumeration);
2180 QCOMPARE(object.propertyFlags("dontEnumProperty"), QScriptValue::SkipInEnumeration);
2181 QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true);
2182 // should not be part of enumeration
2183 {
2184 QScriptValue ret = eng.evaluate(
2185 program: "found = false;"
2186 "for (var p in object) {"
2187 " if (p == 'dontEnumProperty') {"
2188 " found = true; break;"
2189 " }"
2190 "} found");
2191 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, false)), true);
2192 }
2193 // should still be writable
2194 eng.evaluate(program: "object.dontEnumProperty = object.dontEnumProperty + 1");
2195 QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1);
2196 // should still be deletable
2197 {
2198 QScriptValue ret = eng.evaluate(program: "delete object.dontEnumProperty");
2199 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
2200 QCOMPARE(object.property("dontEnumProperty").isValid(), false);
2201 }
2202
2203 // change flags
2204 object.setProperty(name: "flagProperty", value: str);
2205 QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::PropertyFlags{});
2206
2207 object.setProperty(name: "flagProperty", value: str, flags: QScriptValue::ReadOnly);
2208 QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly);
2209
2210 object.setProperty(name: "flagProperty", value: str, flags: object.propertyFlags(name: "flagProperty") | QScriptValue::SkipInEnumeration);
2211 QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
2212
2213 object.setProperty(name: "flagProperty", value: str, flags: QScriptValue::KeepExistingFlags);
2214 QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
2215
2216 object.setProperty(name: "flagProperty", value: str, flags: QScriptValue::UserRange);
2217 QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::UserRange);
2218
2219 // flags of property in the prototype
2220 {
2221 QScriptValue object2 = eng.newObject();
2222 object2.setPrototype(object);
2223 QCOMPARE(object2.propertyFlags("flagProperty", QScriptValue::ResolveLocal), 0);
2224 QCOMPARE(object2.propertyFlags("flagProperty"), QScriptValue::UserRange);
2225 }
2226
2227 // using interned strings
2228 QScriptString foo = eng.toStringHandle(str: "foo");
2229
2230 object.setProperty(name: foo, value: QScriptValue());
2231 QVERIFY(!object.property(foo).isValid());
2232
2233 object.setProperty(name: foo, value: num);
2234 QVERIFY(object.property(foo).strictlyEquals(num));
2235 QVERIFY(object.property("foo").strictlyEquals(num));
2236 QVERIFY(object.propertyFlags(foo) == 0);
2237
2238 // Setting index property on non-Array
2239 object.setProperty(arrayIndex: 13, value: num);
2240 QVERIFY(object.property(13).equals(num));
2241}
2242
2243void tst_QScriptValue::arrayElementGetterSetter()
2244{
2245 QScriptEngine eng;
2246 QScriptValue obj = eng.newObject();
2247 obj.setProperty(arrayIndex: 1, value: eng.newFunction(signature: getterSetter), flags: QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
2248 {
2249 QScriptValue num(123);
2250 obj.setProperty(name: "x", value: num);
2251 QScriptValue ret = obj.property(arrayIndex: 1);
2252 QVERIFY(ret.isValid());
2253 QVERIFY(ret.equals(num));
2254 }
2255 {
2256 QScriptValue num(456);
2257 obj.setProperty(arrayIndex: 1, value: num);
2258 QScriptValue ret = obj.property(arrayIndex: 1);
2259 QVERIFY(ret.isValid());
2260 QVERIFY(ret.equals(num));
2261 QVERIFY(ret.equals(obj.property("1")));
2262 }
2263 QCOMPARE(obj.propertyFlags("1"), QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
2264
2265 obj.setProperty(arrayIndex: 1, value: QScriptValue(), flags: QScriptValue::PropertyGetter|QScriptValue::PropertySetter);
2266 QVERIFY(obj.propertyFlags("1") == 0);
2267}
2268
2269void tst_QScriptValue::getSetPrototype_cyclicPrototype()
2270{
2271 QScriptEngine eng;
2272 QScriptValue prototype = eng.newObject();
2273 QScriptValue object = eng.newObject();
2274 object.setPrototype(prototype);
2275
2276 QScriptValue previousPrototype = prototype.prototype();
2277 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setPrototype() failed: cyclic prototype value");
2278 prototype.setPrototype(prototype);
2279 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2280
2281 object.setPrototype(prototype);
2282 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setPrototype() failed: cyclic prototype value");
2283 prototype.setPrototype(object);
2284 QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
2285
2286}
2287
2288void tst_QScriptValue::getSetPrototype_evalCyclicPrototype()
2289{
2290 QScriptEngine eng;
2291 QScriptValue ret = eng.evaluate(program: "o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
2292 QCOMPARE(eng.hasUncaughtException(), true);
2293 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
2294 QCOMPARE(ret.isError(), true);
2295 QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
2296}
2297
2298void tst_QScriptValue::getSetPrototype_eval()
2299{
2300 QScriptEngine eng;
2301 QScriptValue ret = eng.evaluate(program: "p = { }; p.__proto__ = { }");
2302 QCOMPARE(eng.hasUncaughtException(), false);
2303 QCOMPARE(ret.isError(), false);
2304}
2305
2306void tst_QScriptValue::getSetPrototype_invalidPrototype()
2307{
2308 QScriptEngine eng;
2309 QScriptValue inv;
2310 QScriptValue object = eng.newObject();
2311 QScriptValue proto = object.prototype();
2312 QVERIFY(object.prototype().strictlyEquals(proto));
2313 inv.setPrototype(object);
2314 QCOMPARE(inv.prototype().isValid(), false);
2315 object.setPrototype(inv);
2316 QVERIFY(object.prototype().strictlyEquals(proto));
2317}
2318
2319void tst_QScriptValue::getSetPrototype_twoEngines()
2320{
2321 QScriptEngine eng;
2322 QScriptValue prototype = eng.newObject();
2323 QScriptValue object = eng.newObject();
2324 object.setPrototype(prototype);
2325 QScriptEngine otherEngine;
2326 QScriptValue newPrototype = otherEngine.newObject();
2327 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
2328 object.setPrototype(newPrototype);
2329 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2330
2331}
2332
2333void tst_QScriptValue::getSetPrototype_null()
2334{
2335 QScriptEngine eng;
2336 QScriptValue object = eng.newObject();
2337 object.setPrototype(QScriptValue(QScriptValue::NullValue));
2338 QVERIFY(object.prototype().isNull());
2339
2340 QScriptValue newProto = eng.newObject();
2341 object.setPrototype(newProto);
2342 QVERIFY(object.prototype().equals(newProto));
2343
2344 object.setPrototype(QScriptValue(&eng, QScriptValue::NullValue));
2345 QVERIFY(object.prototype().isNull());
2346}
2347
2348void tst_QScriptValue::getSetPrototype_notObjectOrNull()
2349{
2350 QScriptEngine eng;
2351 QScriptValue object = eng.newObject();
2352 QScriptValue originalProto = object.prototype();
2353
2354 // bool
2355 object.setPrototype(true);
2356 QVERIFY(object.prototype().equals(originalProto));
2357 object.setPrototype(QScriptValue(&eng, true));
2358 QVERIFY(object.prototype().equals(originalProto));
2359
2360 // number
2361 object.setPrototype(123);
2362 QVERIFY(object.prototype().equals(originalProto));
2363 object.setPrototype(QScriptValue(&eng, 123));
2364 QVERIFY(object.prototype().equals(originalProto));
2365
2366 // string
2367 object.setPrototype("foo");
2368 QVERIFY(object.prototype().equals(originalProto));
2369 object.setPrototype(QScriptValue(&eng, "foo"));
2370 QVERIFY(object.prototype().equals(originalProto));
2371
2372 // undefined
2373 object.setPrototype(QScriptValue(QScriptValue::UndefinedValue));
2374 QVERIFY(object.prototype().equals(originalProto));
2375 object.setPrototype(QScriptValue(&eng, QScriptValue::UndefinedValue));
2376 QVERIFY(object.prototype().equals(originalProto));
2377}
2378
2379void tst_QScriptValue::getSetPrototype()
2380{
2381 QScriptEngine eng;
2382 QScriptValue prototype = eng.newObject();
2383 QScriptValue object = eng.newObject();
2384 object.setPrototype(prototype);
2385 QCOMPARE(object.prototype().strictlyEquals(prototype), true);
2386}
2387
2388void tst_QScriptValue::getSetScope()
2389{
2390 QScriptEngine eng;
2391
2392 QScriptValue object = eng.newObject();
2393 QCOMPARE(object.scope().isValid(), false);
2394
2395 QScriptValue object2 = eng.newObject();
2396 object2.setScope(object);
2397
2398 QCOMPARE(object2.scope().strictlyEquals(object), true);
2399
2400 object.setProperty(name: "foo", value: 123);
2401 QVERIFY(!object2.property("foo").isValid());
2402 {
2403 QScriptValue ret = object2.property(name: "foo", mode: QScriptValue::ResolveScope);
2404 QVERIFY(ret.isNumber());
2405 QCOMPARE(ret.toInt32(), 123);
2406 }
2407
2408 QScriptValue inv;
2409 inv.setScope(object);
2410 QCOMPARE(inv.scope().isValid(), false);
2411
2412 QScriptEngine otherEngine;
2413 QScriptValue object3 = otherEngine.newObject();
2414 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setScope() failed: cannot set a scope object created in a different engine");
2415 object2.setScope(object3);
2416 QCOMPARE(object2.scope().strictlyEquals(object), true);
2417
2418 object2.setScope(QScriptValue());
2419 QVERIFY(!object2.scope().isValid());
2420}
2421
2422void tst_QScriptValue::getSetData_objects_data()
2423{
2424 newEngine();
2425
2426 QTest::addColumn<QScriptValue>(name: "object");
2427
2428 QTest::newRow(dataTag: "object from evaluate") << engine->evaluate(program: "new Object()");
2429 QTest::newRow(dataTag: "object from engine") << engine->newObject();
2430 QTest::newRow(dataTag: "Array") << engine->newArray();
2431 QTest::newRow(dataTag: "Date") << engine->newDate(value: 12324);
2432 QTest::newRow(dataTag: "QObject") << engine->newQObject(object: this);
2433 QTest::newRow(dataTag: "RegExp") << engine->newRegExp(regexp: QRegExp());
2434}
2435
2436void tst_QScriptValue::getSetData_objects()
2437{
2438 QFETCH(QScriptValue, object);
2439
2440 QVERIFY(!object.data().isValid());
2441 QScriptValue v1(true);
2442 object.setData(v1);
2443 QVERIFY(object.data().strictlyEquals(v1));
2444 QScriptValue v2(123);
2445 object.setData(v2);
2446 QVERIFY(object.data().strictlyEquals(v2));
2447 QScriptValue v3 = engine->newObject();
2448 object.setData(v3);
2449 QVERIFY(object.data().strictlyEquals(v3));
2450 object.setData(QScriptValue());
2451 QVERIFY(!object.data().isValid());
2452}
2453
2454void tst_QScriptValue::getSetData_nonObjects_data()
2455{
2456 newEngine();
2457
2458 QTest::addColumn<QScriptValue>(name: "value");
2459
2460 QTest::newRow(dataTag: "undefined (bound)") << engine->undefinedValue();
2461 QTest::newRow(dataTag: "null (bound)") << engine->nullValue();
2462 QTest::newRow(dataTag: "string (bound)") << QScriptValue(engine, "Pong");
2463 QTest::newRow(dataTag: "bool (bound)") << QScriptValue(engine, false);
2464
2465 QTest::newRow(dataTag: "undefined") << QScriptValue(QScriptValue::UndefinedValue);
2466 QTest::newRow(dataTag: "null") << QScriptValue(QScriptValue::NullValue);
2467 QTest::newRow(dataTag: "string") << QScriptValue("Pong");
2468 QTest::newRow(dataTag: "bool") << QScriptValue(true);
2469}
2470
2471void tst_QScriptValue::getSetData_nonObjects()
2472{
2473 QFETCH(QScriptValue, value);
2474
2475 QVERIFY(!value.data().isValid());
2476 QScriptValue v1(true);
2477 value.setData(v1);
2478 QVERIFY(!value.data().isValid());
2479 QScriptValue v2(123);
2480 value.setData(v2);
2481 QVERIFY(!value.data().isValid());
2482 QScriptValue v3 = engine->newObject();
2483 value.setData(v3);
2484 QVERIFY(!value.data().isValid());
2485 value.setData(QScriptValue());
2486 QVERIFY(!value.data().isValid());
2487}
2488
2489void tst_QScriptValue::setData_QTBUG15144()
2490{
2491 QScriptEngine eng;
2492 QScriptValue obj = eng.newObject();
2493 for (int i = 0; i < 10000; ++i) {
2494 // Create an object with property 'fooN' on it, and immediately kill
2495 // the reference to the object so it and the property name become garbage.
2496 eng.evaluate(program: QString::fromLatin1(str: "o = {}; o.foo%0 = 10; o = null;").arg(a: i));
2497 // Setting the data will cause a JS string to be allocated, which could
2498 // trigger a GC. This should not cause a crash.
2499 obj.setData("foodfight");
2500 }
2501}
2502
2503class TestScriptClass : public QScriptClass
2504{
2505public:
2506 TestScriptClass(QScriptEngine *engine) : QScriptClass(engine) {}
2507};
2508
2509void tst_QScriptValue::getSetScriptClass_emptyClass_data()
2510{
2511 newEngine();
2512 QTest::addColumn<QScriptValue>(name: "value");
2513
2514 QTest::newRow(dataTag: "invalid") << QScriptValue();
2515 QTest::newRow(dataTag: "number") << QScriptValue(123);
2516 QTest::newRow(dataTag: "string") << QScriptValue("pong");
2517 QTest::newRow(dataTag: "bool") << QScriptValue(false);
2518 QTest::newRow(dataTag: "null") << QScriptValue(QScriptValue::NullValue);
2519 QTest::newRow(dataTag: "undefined") << QScriptValue(QScriptValue::UndefinedValue);
2520
2521 QTest::newRow(dataTag: "number") << QScriptValue(engine, 123);
2522 QTest::newRow(dataTag: "string") << QScriptValue(engine, "pong");
2523 QTest::newRow(dataTag: "bool") << QScriptValue(engine, true);
2524 QTest::newRow(dataTag: "null") << QScriptValue(engine->nullValue());
2525 QTest::newRow(dataTag: "undefined") << QScriptValue(engine->undefinedValue());
2526 QTest::newRow(dataTag: "object") << QScriptValue(engine->newObject());
2527 QTest::newRow(dataTag: "date") << QScriptValue(engine->evaluate(program: "new Date()"));
2528 QTest::newRow(dataTag: "qobject") << QScriptValue(engine->newQObject(object: this));
2529}
2530
2531void tst_QScriptValue::getSetScriptClass_emptyClass()
2532{
2533 QFETCH(QScriptValue, value);
2534 QCOMPARE(value.scriptClass(), (QScriptClass*)0);
2535}
2536
2537void tst_QScriptValue::getSetScriptClass_JSObjectFromCpp()
2538{
2539 QScriptEngine eng;
2540 TestScriptClass testClass(&eng);
2541 // object created in C++ (newObject())
2542 {
2543 QScriptValue obj = eng.newObject();
2544 obj.setScriptClass(&testClass);
2545 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2546 obj.setScriptClass(0);
2547 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2548 }
2549}
2550
2551void tst_QScriptValue::getSetScriptClass_JSObjectFromJS()
2552{
2553 QScriptEngine eng;
2554 TestScriptClass testClass(&eng);
2555 // object created in JS
2556 {
2557 QScriptValue obj = eng.evaluate(program: "new Object");
2558 QVERIFY(!eng.hasUncaughtException());
2559 QVERIFY(obj.isObject());
2560 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2561 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setScriptClass() failed: cannot change class of non-QScriptObject");
2562 obj.setScriptClass(&testClass);
2563 QEXPECT_FAIL("", "With JSC back-end, the class of a plain object created in JS can't be changed", Continue);
2564 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2565 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::setScriptClass() failed: cannot change class of non-QScriptObject");
2566 obj.setScriptClass(0);
2567 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2568 }
2569}
2570
2571void tst_QScriptValue::getSetScriptClass_QVariant()
2572{
2573 QScriptEngine eng;
2574 TestScriptClass testClass(&eng);
2575 // object that already has a(n internal) class
2576 {
2577 QScriptValue obj = eng.newVariant(value: QUrl("http://example.com"));
2578 QVERIFY(obj.isVariant());
2579 QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
2580 obj.setScriptClass(&testClass);
2581 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2582 QVERIFY(obj.isObject());
2583 QVERIFY(!obj.isVariant());
2584 QCOMPARE(obj.toVariant(), QVariant(QVariantMap()));
2585 }
2586}
2587
2588void tst_QScriptValue::getSetScriptClass_QObject()
2589{
2590 QScriptEngine eng;
2591 TestScriptClass testClass(&eng);
2592 {
2593 QScriptValue obj = eng.newQObject(object: this);
2594 QVERIFY(obj.isQObject());
2595 obj.setScriptClass(&testClass);
2596 QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
2597 QVERIFY(obj.isObject());
2598 QVERIFY(!obj.isQObject());
2599 QVERIFY(obj.toQObject() == 0);
2600 }
2601}
2602
2603static QScriptValue getArg(QScriptContext *ctx, QScriptEngine *)
2604{
2605 return ctx->argument(index: 0);
2606}
2607
2608static QScriptValue evaluateArg(QScriptContext *, QScriptEngine *eng)
2609{
2610 return eng->evaluate(program: "arguments[0]");
2611}
2612
2613static QScriptValue addArgs(QScriptContext *, QScriptEngine *eng)
2614{
2615 return eng->evaluate(program: "arguments[0] + arguments[1]");
2616}
2617
2618static QScriptValue returnInvalidValue(QScriptContext *, QScriptEngine *)
2619{
2620 return QScriptValue();
2621}
2622
2623void tst_QScriptValue::call_function()
2624{
2625 QScriptEngine eng;
2626 QScriptValue fun = eng.evaluate(program: "(function() { return 1; })");
2627 QVERIFY(fun.isFunction());
2628 QScriptValue result = fun.call();
2629 QVERIFY(result.isNumber());
2630 QCOMPARE(result.toInt32(), 1);
2631}
2632
2633void tst_QScriptValue::call_object()
2634{
2635 QScriptEngine eng;
2636 QScriptValue Object = eng.evaluate(program: "Object");
2637 QCOMPARE(Object.isFunction(), true);
2638 QScriptValue result = Object.call(thisObject: Object);
2639 QCOMPARE(result.isObject(), true);
2640}
2641
2642void tst_QScriptValue::call_newObjects()
2643{
2644 QScriptEngine eng;
2645 // test that call() doesn't construct new objects
2646 QScriptValue Number = eng.evaluate(program: "Number");
2647 QScriptValue Object = eng.evaluate(program: "Object");
2648 QCOMPARE(Object.isFunction(), true);
2649 QScriptValueList args;
2650 args << QScriptValue(&eng, 123);
2651 QScriptValue result = Number.call(thisObject: Object, args);
2652 QCOMPARE(result.strictlyEquals(args.at(0)), true);
2653}
2654
2655void tst_QScriptValue::call_this()
2656{
2657 QScriptEngine eng;
2658 // test that correct "this" object is used
2659 QScriptValue fun = eng.evaluate(program: "(function() { return this; })");
2660 QCOMPARE(fun.isFunction(), true);
2661
2662 QScriptValue numberObject = QScriptValue(&eng, 123.0).toObject();
2663 QScriptValue result = fun.call(thisObject: numberObject);
2664 QCOMPARE(result.isObject(), true);
2665 QCOMPARE(result.toNumber(), 123.0);
2666}
2667
2668void tst_QScriptValue::call_arguments()
2669{
2670 QScriptEngine eng;
2671 // test that correct arguments are passed
2672
2673 QScriptValue fun = eng.evaluate(program: "(function() { return arguments[0]; })");
2674 QCOMPARE(fun.isFunction(), true);
2675 {
2676 QScriptValue result = fun.call(thisObject: eng.undefinedValue());
2677 QCOMPARE(result.isUndefined(), true);
2678 }
2679 {
2680 QScriptValueList args;
2681 args << QScriptValue(&eng, 123.0);
2682 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2683 QCOMPARE(result.isNumber(), true);
2684 QCOMPARE(result.toNumber(), 123.0);
2685 }
2686 // V2 constructors
2687 {
2688 QScriptValueList args;
2689 args << QScriptValue(123.0);
2690 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2691 QCOMPARE(result.isNumber(), true);
2692 QCOMPARE(result.toNumber(), 123.0);
2693 }
2694 {
2695 QScriptValue args = eng.newArray();
2696 args.setProperty(arrayIndex: 0, value: 123);
2697 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), arguments: args);
2698 QVERIFY(result.isNumber());
2699 QCOMPARE(result.toNumber(), 123.0);
2700 }
2701}
2702
2703void tst_QScriptValue::call()
2704{
2705 QScriptEngine eng;
2706 {
2707 QScriptValue fun = eng.evaluate(program: "(function() { return arguments[1]; })");
2708 QCOMPARE(fun.isFunction(), true);
2709
2710 {
2711 QScriptValueList args;
2712 args << QScriptValue(&eng, 123.0) << QScriptValue(&eng, 456.0);
2713 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2714 QCOMPARE(result.isNumber(), true);
2715 QCOMPARE(result.toNumber(), 456.0);
2716 }
2717 {
2718 QScriptValue args = eng.newArray();
2719 args.setProperty(arrayIndex: 0, value: 123);
2720 args.setProperty(arrayIndex: 1, value: 456);
2721 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), arguments: args);
2722 QVERIFY(result.isNumber());
2723 QCOMPARE(result.toNumber(), 456.0);
2724 }
2725 }
2726 {
2727 QScriptValue fun = eng.evaluate(program: "(function() { throw new Error('foo'); })");
2728 QCOMPARE(fun.isFunction(), true);
2729 QVERIFY(!eng.hasUncaughtException());
2730
2731 {
2732 QScriptValue result = fun.call();
2733 QCOMPARE(result.isError(), true);
2734 QCOMPARE(eng.hasUncaughtException(), true);
2735 QVERIFY(result.strictlyEquals(eng.uncaughtException()));
2736 }
2737 }
2738 {
2739 eng.clearExceptions();
2740 QScriptValue fun = eng.newFunction(signature: getArg);
2741 {
2742 QScriptValueList args;
2743 args << QScriptValue(&eng, 123.0);
2744 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2745 QVERIFY(!eng.hasUncaughtException());
2746 QCOMPARE(result.isNumber(), true);
2747 QCOMPARE(result.toNumber(), 123.0);
2748 }
2749 // V2 constructors
2750 {
2751 QScriptValueList args;
2752 args << QScriptValue(123.0);
2753 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2754 QCOMPARE(result.isNumber(), true);
2755 QCOMPARE(result.toNumber(), 123.0);
2756 }
2757 {
2758 QScriptValue args = eng.newArray();
2759 args.setProperty(arrayIndex: 0, value: 123);
2760 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), arguments: args);
2761 QVERIFY(result.isNumber());
2762 QCOMPARE(result.toNumber(), 123.0);
2763 }
2764 }
2765 {
2766 QScriptValue fun = eng.newFunction(signature: evaluateArg);
2767 {
2768 QScriptValueList args;
2769 args << QScriptValue(&eng, 123.0);
2770 QScriptValue result = fun.call(thisObject: eng.undefinedValue(), args);
2771 QVERIFY(!eng.hasUncaughtException());
2772 QCOMPARE(result.isNumber(), true);
2773 QCOMPARE(result.toNumber(), 123.0);
2774 }
2775 }
2776}
2777
2778void tst_QScriptValue::call_invalidArguments()
2779{
2780 // test that invalid arguments are handled gracefully
2781 QScriptEngine eng;
2782 {
2783 QScriptValue fun = eng.newFunction(signature: getArg);
2784 {
2785 QScriptValueList args;
2786 args << QScriptValue();
2787 QScriptValue ret = fun.call(thisObject: QScriptValue(), args);
2788 QVERIFY(!eng.hasUncaughtException());
2789 QCOMPARE(ret.isValid(), true);
2790 QCOMPARE(ret.isUndefined(), true);
2791 }
2792 }
2793 {
2794 QScriptValue fun = eng.newFunction(signature: evaluateArg);
2795 {
2796 QScriptValueList args;
2797 args << QScriptValue();
2798 QScriptValue ret = fun.call(thisObject: QScriptValue(), args);
2799 QCOMPARE(ret.isValid(), true);
2800 QCOMPARE(ret.isUndefined(), true);
2801 }
2802 }
2803 {
2804 QScriptValue fun = eng.newFunction(signature: addArgs);
2805 {
2806 QScriptValueList args;
2807 args << QScriptValue() << QScriptValue();
2808 QScriptValue ret = fun.call(thisObject: QScriptValue(), args);
2809 QCOMPARE(ret.isValid(), true);
2810 QCOMPARE(ret.isNumber(), true);
2811 QCOMPARE(qIsNaN(ret.toNumber()), true);
2812 }
2813 }
2814}
2815
2816void tst_QScriptValue::call_invalidReturn()
2817{
2818 // test that invalid return value is handled gracefully
2819 QScriptEngine eng;
2820 QScriptValue fun = eng.newFunction(signature: returnInvalidValue);
2821 eng.globalObject().setProperty(name: "returnInvalidValue", value: fun);
2822 QScriptValue ret = eng.evaluate(program: "returnInvalidValue() + returnInvalidValue()");
2823 QCOMPARE(ret.isValid(), true);
2824 QCOMPARE(ret.isNumber(), true);
2825 QCOMPARE(qIsNaN(ret.toNumber()), true);
2826}
2827
2828void tst_QScriptValue::call_twoEngines()
2829{
2830 QScriptEngine eng;
2831 QScriptValue object = eng.evaluate(program: "Object");
2832 QScriptEngine otherEngine;
2833 QScriptValue fun = otherEngine.evaluate(program: "(function() { return 1; })");
2834 QVERIFY(fun.isFunction());
2835 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::call() failed: "
2836 "cannot call function with thisObject created in "
2837 "a different engine");
2838 QCOMPARE(fun.call(object).isValid(), false);
2839 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::call() failed: "
2840 "cannot call function with argument created in "
2841 "a different engine");
2842 QCOMPARE(fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123)).isValid(), false);
2843 {
2844 QScriptValue fun = eng.evaluate(program: "Object");
2845 QVERIFY(fun.isFunction());
2846 QScriptEngine eng2;
2847 QScriptValue objectInDifferentEngine = eng2.newObject();
2848 QScriptValueList args;
2849 args << objectInDifferentEngine;
2850 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::call() failed: cannot call function with argument created in a different engine");
2851 fun.call(thisObject: QScriptValue(), args);
2852 }
2853}
2854
2855void tst_QScriptValue::call_array()
2856{
2857 QScriptEngine eng;
2858 QScriptValue fun = eng.evaluate(program: "(function() { return arguments; })");
2859 QVERIFY(fun.isFunction());
2860 QScriptValue array = eng.newArray(length: 3);
2861 array.setProperty(arrayIndex: 0, value: QScriptValue(&eng, 123.0));
2862 array.setProperty(arrayIndex: 1, value: QScriptValue(&eng, 456.0));
2863 array.setProperty(arrayIndex: 2, value: QScriptValue(&eng, 789.0));
2864 // call with single array object as arguments
2865 QScriptValue ret = fun.call(thisObject: QScriptValue(), arguments: array);
2866 QVERIFY(!eng.hasUncaughtException());
2867 QCOMPARE(ret.isError(), false);
2868 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
2869 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
2870 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
2871 // call with arguments object as arguments
2872 QScriptValue ret2 = fun.call(thisObject: QScriptValue(), arguments: ret);
2873 QCOMPARE(ret2.isError(), false);
2874 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
2875 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
2876 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
2877 // call with null as arguments
2878 QScriptValue ret3 = fun.call(thisObject: QScriptValue(), arguments: eng.nullValue());
2879 QCOMPARE(ret3.isError(), false);
2880 QCOMPARE(ret3.property("length").isNumber(), true);
2881 QCOMPARE(ret3.property("length").toNumber(), 0.0);
2882 // call with undefined as arguments
2883 QScriptValue ret4 = fun.call(thisObject: QScriptValue(), arguments: eng.undefinedValue());
2884 QCOMPARE(ret4.isError(), false);
2885 QCOMPARE(ret4.property("length").isNumber(), true);
2886 QCOMPARE(ret4.property("length").toNumber(), 0.0);
2887 // call with something else as arguments
2888 QScriptValue ret5 = fun.call(thisObject: QScriptValue(), arguments: QScriptValue(&eng, 123.0));
2889 QCOMPARE(ret5.isError(), true);
2890 // call with a non-array object as arguments
2891 QScriptValue ret6 = fun.call(thisObject: QScriptValue(), arguments: eng.globalObject());
2892 QVERIFY(ret6.isError());
2893 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
2894}
2895
2896
2897void tst_QScriptValue::call_nonFunction_data()
2898{
2899 newEngine();
2900 QTest::addColumn<QScriptValue>(name: "value");
2901
2902 QTest::newRow(dataTag: "invalid") << QScriptValue();
2903 QTest::newRow(dataTag: "bool") << QScriptValue(false);
2904 QTest::newRow(dataTag: "int") << QScriptValue(123);
2905 QTest::newRow(dataTag: "string") << QScriptValue(QString::fromLatin1(str: "ciao"));
2906 QTest::newRow(dataTag: "undefined") << QScriptValue(QScriptValue::UndefinedValue);
2907 QTest::newRow(dataTag: "null") << QScriptValue(QScriptValue::NullValue);
2908
2909 QTest::newRow(dataTag: "bool bound") << QScriptValue(engine, false);
2910 QTest::newRow(dataTag: "int bound") << QScriptValue(engine, 123);
2911 QTest::newRow(dataTag: "string bound") << QScriptValue(engine, QString::fromLatin1(str: "ciao"));
2912 QTest::newRow(dataTag: "undefined bound") << engine->undefinedValue();
2913 QTest::newRow(dataTag: "null bound") << engine->nullValue();
2914}
2915
2916void tst_QScriptValue::call_nonFunction()
2917{
2918 // calling things that are not functions
2919 QFETCH(QScriptValue, value);
2920 QVERIFY(!value.call().isValid());
2921}
2922
2923static QScriptValue ctorReturningUndefined(QScriptContext *ctx, QScriptEngine *)
2924{
2925 ctx->thisObject().setProperty(name: "foo", value: 123);
2926 return QScriptValue(QScriptValue::UndefinedValue);
2927}
2928
2929static QScriptValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng)
2930{
2931 QScriptValue result = eng->newObject();
2932 result.setProperty(name: "bar", value: 456);
2933 return result;
2934}
2935
2936void tst_QScriptValue::construct_nonFunction_data()
2937{
2938 newEngine();
2939 QTest::addColumn<QScriptValue>(name: "value");
2940
2941 QTest::newRow(dataTag: "invalid") << QScriptValue();
2942 QTest::newRow(dataTag: "bool") << QScriptValue(false);
2943 QTest::newRow(dataTag: "int") << QScriptValue(123);
2944 QTest::newRow(dataTag: "string") << QScriptValue(QString::fromLatin1(str: "ciao"));
2945 QTest::newRow(dataTag: "undefined") << QScriptValue(QScriptValue::UndefinedValue);
2946 QTest::newRow(dataTag: "null") << QScriptValue(QScriptValue::NullValue);
2947
2948 QTest::newRow(dataTag: "bool bound") << QScriptValue(engine, false);
2949 QTest::newRow(dataTag: "int bound") << QScriptValue(engine, 123);
2950 QTest::newRow(dataTag: "string bound") << QScriptValue(engine, QString::fromLatin1(str: "ciao"));
2951 QTest::newRow(dataTag: "undefined bound") << engine->undefinedValue();
2952 QTest::newRow(dataTag: "null bound") << engine->nullValue();
2953}
2954
2955void tst_QScriptValue::construct_nonFunction()
2956{
2957 QFETCH(QScriptValue, value);
2958 QVERIFY(!value.construct().isValid());
2959}
2960
2961void tst_QScriptValue::construct_simple()
2962{
2963 QScriptEngine eng;
2964 QScriptValue fun = eng.evaluate(program: "(function () { this.foo = 123; })");
2965 QVERIFY(fun.isFunction());
2966 QScriptValue ret = fun.construct();
2967 QVERIFY(ret.isObject());
2968 QVERIFY(ret.instanceOf(fun));
2969 QCOMPARE(ret.property("foo").toInt32(), 123);
2970}
2971
2972void tst_QScriptValue::construct_newObjectJS()
2973{
2974 QScriptEngine eng;
2975 // returning a different object overrides the default-constructed one
2976 QScriptValue fun = eng.evaluate(program: "(function () { return { bar: 456 }; })");
2977 QVERIFY(fun.isFunction());
2978 QScriptValue ret = fun.construct();
2979 QVERIFY(ret.isObject());
2980 QVERIFY(!ret.instanceOf(fun));
2981 QCOMPARE(ret.property("bar").toInt32(), 456);
2982}
2983
2984void tst_QScriptValue::construct_undefined()
2985{
2986 QScriptEngine eng;
2987 QScriptValue fun = eng.newFunction(signature: ctorReturningUndefined);
2988 QScriptValue ret = fun.construct();
2989 QVERIFY(ret.isObject());
2990 QVERIFY(ret.instanceOf(fun));
2991 QCOMPARE(ret.property("foo").toInt32(), 123);
2992}
2993
2994void tst_QScriptValue::construct_newObjectCpp()
2995{
2996 QScriptEngine eng;
2997 QScriptValue fun = eng.newFunction(signature: ctorReturningNewObject);
2998 QScriptValue ret = fun.construct();
2999 QVERIFY(ret.isObject());
3000 QVERIFY(!ret.instanceOf(fun));
3001 QCOMPARE(ret.property("bar").toInt32(), 456);
3002}
3003
3004void tst_QScriptValue::construct_arg()
3005{
3006 QScriptEngine eng;
3007 QScriptValue Number = eng.evaluate(program: "Number");
3008 QCOMPARE(Number.isFunction(), true);
3009 QScriptValueList args;
3010 args << QScriptValue(&eng, 123);
3011 QScriptValue ret = Number.construct(args);
3012 QCOMPARE(ret.isObject(), true);
3013 QCOMPARE(ret.toNumber(), args.at(0).toNumber());
3014}
3015
3016void tst_QScriptValue::construct_proto()
3017{
3018 QScriptEngine eng;
3019 // test that internal prototype is set correctly
3020 QScriptValue fun = eng.evaluate(program: "(function() { return this.__proto__; })");
3021 QCOMPARE(fun.isFunction(), true);
3022 QCOMPARE(fun.property("prototype").isObject(), true);
3023 QScriptValue ret = fun.construct();
3024 QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
3025}
3026
3027void tst_QScriptValue::construct_returnInt()
3028{
3029 QScriptEngine eng;
3030 // test that we return the new object even if a non-object value is returned from the function
3031 QScriptValue fun = eng.evaluate(program: "(function() { return 123; })");
3032 QCOMPARE(fun.isFunction(), true);
3033 QScriptValue ret = fun.construct();
3034 QCOMPARE(ret.isObject(), true);
3035}
3036
3037void tst_QScriptValue::construct_throw()
3038{
3039 QScriptEngine eng;
3040 QScriptValue fun = eng.evaluate(program: "(function() { throw new Error('foo'); })");
3041 QCOMPARE(fun.isFunction(), true);
3042 QScriptValue ret = fun.construct();
3043 QCOMPARE(ret.isError(), true);
3044 QCOMPARE(eng.hasUncaughtException(), true);
3045 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3046}
3047
3048void tst_QScriptValue::construct()
3049{
3050 QScriptEngine eng;
3051 QScriptValue fun = eng.evaluate(program: "(function() { return arguments; })");
3052 QVERIFY(fun.isFunction());
3053 QScriptValue array = eng.newArray(length: 3);
3054 array.setProperty(arrayIndex: 0, value: QScriptValue(&eng, 123.0));
3055 array.setProperty(arrayIndex: 1, value: QScriptValue(&eng, 456.0));
3056 array.setProperty(arrayIndex: 2, value: QScriptValue(&eng, 789.0));
3057 // construct with single array object as arguments
3058 QScriptValue ret = fun.construct(arguments: array);
3059 QVERIFY(!eng.hasUncaughtException());
3060 QVERIFY(ret.isValid());
3061 QVERIFY(ret.isObject());
3062 QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
3063 QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
3064 QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
3065 // construct with arguments object as arguments
3066 QScriptValue ret2 = fun.construct(arguments: ret);
3067 QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
3068 QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
3069 QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
3070 // construct with null as arguments
3071 QScriptValue ret3 = fun.construct(arguments: eng.nullValue());
3072 QCOMPARE(ret3.isError(), false);
3073 QCOMPARE(ret3.property("length").isNumber(), true);
3074 QCOMPARE(ret3.property("length").toNumber(), 0.0);
3075 // construct with undefined as arguments
3076 QScriptValue ret4 = fun.construct(arguments: eng.undefinedValue());
3077 QCOMPARE(ret4.isError(), false);
3078 QCOMPARE(ret4.property("length").isNumber(), true);
3079 QCOMPARE(ret4.property("length").toNumber(), 0.0);
3080 // construct with something else as arguments
3081 QScriptValue ret5 = fun.construct(arguments: QScriptValue(&eng, 123.0));
3082 QCOMPARE(ret5.isError(), true);
3083 // construct with a non-array object as arguments
3084 QScriptValue ret6 = fun.construct(arguments: eng.globalObject());
3085 QVERIFY(ret6.isError());
3086 QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
3087}
3088
3089void tst_QScriptValue::construct_twoEngines()
3090{
3091 QScriptEngine engine;
3092 QScriptEngine otherEngine;
3093 QScriptValue ctor = engine.evaluate(program: "(function (a, b) { this.foo = 123; })");
3094 QScriptValue arg(&otherEngine, 124567);
3095 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
3096 QVERIFY(!ctor.construct(arg).isValid());
3097 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
3098 QVERIFY(!ctor.construct(QScriptValueList() << arg << otherEngine.newObject()).isValid());
3099}
3100
3101void tst_QScriptValue::construct_constructorThrowsPrimitive()
3102{
3103 QScriptEngine eng;
3104 QScriptValue fun = eng.evaluate(program: "(function() { throw 123; })");
3105 QVERIFY(fun.isFunction());
3106 // construct(QScriptValueList)
3107 {
3108 QScriptValue ret = fun.construct();
3109 QVERIFY(ret.isNumber());
3110 QCOMPARE(ret.toNumber(), 123.0);
3111 QVERIFY(eng.hasUncaughtException());
3112 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3113 eng.clearExceptions();
3114 }
3115 // construct(QScriptValue)
3116 {
3117 QScriptValue ret = fun.construct(arguments: eng.newArray());
3118 QVERIFY(ret.isNumber());
3119 QCOMPARE(ret.toNumber(), 123.0);
3120 QVERIFY(eng.hasUncaughtException());
3121 QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
3122 eng.clearExceptions();
3123 }
3124}
3125
3126void tst_QScriptValue::lessThan()
3127{
3128 QScriptEngine eng;
3129
3130 QVERIFY(!QScriptValue().lessThan(QScriptValue()));
3131
3132 QScriptValue num = QScriptValue(&eng, 123);
3133 QCOMPARE(num.lessThan(QScriptValue(&eng, 124)), true);
3134 QCOMPARE(num.lessThan(QScriptValue(&eng, 122)), false);
3135 QCOMPARE(num.lessThan(QScriptValue(&eng, 123)), false);
3136 QCOMPARE(num.lessThan(QScriptValue(&eng, "124")), true);
3137 QCOMPARE(num.lessThan(QScriptValue(&eng, "122")), false);
3138 QCOMPARE(num.lessThan(QScriptValue(&eng, "123")), false);
3139 QCOMPARE(num.lessThan(QScriptValue(&eng, qSNaN())), false);
3140 QCOMPARE(num.lessThan(QScriptValue(&eng, +qInf())), true);
3141 QCOMPARE(num.lessThan(QScriptValue(&eng, -qInf())), false);
3142 QCOMPARE(num.lessThan(num), false);
3143 QCOMPARE(num.lessThan(QScriptValue(&eng, 124).toObject()), true);
3144 QCOMPARE(num.lessThan(QScriptValue(&eng, 122).toObject()), false);
3145 QCOMPARE(num.lessThan(QScriptValue(&eng, 123).toObject()), false);
3146 QCOMPARE(num.lessThan(QScriptValue(&eng, "124").toObject()), true);
3147 QCOMPARE(num.lessThan(QScriptValue(&eng, "122").toObject()), false);
3148 QCOMPARE(num.lessThan(QScriptValue(&eng, "123").toObject()), false);
3149 QCOMPARE(num.lessThan(QScriptValue(&eng, qSNaN()).toObject()), false);
3150 QCOMPARE(num.lessThan(QScriptValue(&eng, +qInf()).toObject()), true);
3151 QCOMPARE(num.lessThan(QScriptValue(&eng, -qInf()).toObject()), false);
3152 QCOMPARE(num.lessThan(num.toObject()), false);
3153 QCOMPARE(num.lessThan(QScriptValue()), false);
3154
3155 QScriptValue str = QScriptValue(&eng, "123");
3156 QCOMPARE(str.lessThan(QScriptValue(&eng, "124")), true);
3157 QCOMPARE(str.lessThan(QScriptValue(&eng, "122")), false);
3158 QCOMPARE(str.lessThan(QScriptValue(&eng, "123")), false);
3159 QCOMPARE(str.lessThan(QScriptValue(&eng, 124)), true);
3160 QCOMPARE(str.lessThan(QScriptValue(&eng, 122)), false);
3161 QCOMPARE(str.lessThan(QScriptValue(&eng, 123)), false);
3162 QCOMPARE(str.lessThan(str), false);
3163 QCOMPARE(str.lessThan(QScriptValue(&eng, "124").toObject()), true);
3164 QCOMPARE(str.lessThan(QScriptValue(&eng, "122").toObject()), false);
3165 QCOMPARE(str.lessThan(QScriptValue(&eng, "123").toObject()), false);
3166 QCOMPARE(str.lessThan(QScriptValue(&eng, 124).toObject()), true);
3167 QCOMPARE(str.lessThan(QScriptValue(&eng, 122).toObject()), false);
3168 QCOMPARE(str.lessThan(QScriptValue(&eng, 123).toObject()), false);
3169 QCOMPARE(str.lessThan(str.toObject()), false);
3170 QCOMPARE(str.lessThan(QScriptValue()), false);
3171
3172 // V2 constructors
3173 QScriptValue num2 = QScriptValue(123);
3174 QCOMPARE(num2.lessThan(QScriptValue(124)), true);
3175 QCOMPARE(num2.lessThan(QScriptValue(122)), false);
3176 QCOMPARE(num2.lessThan(QScriptValue(123)), false);
3177 QCOMPARE(num2.lessThan(QScriptValue("124")), true);
3178 QCOMPARE(num2.lessThan(QScriptValue("122")), false);
3179 QCOMPARE(num2.lessThan(QScriptValue("123")), false);
3180 QCOMPARE(num2.lessThan(QScriptValue(qSNaN())), false);
3181 QCOMPARE(num2.lessThan(QScriptValue(+qInf())), true);
3182 QCOMPARE(num2.lessThan(QScriptValue(-qInf())), false);
3183 QCOMPARE(num2.lessThan(num), false);
3184 QCOMPARE(num2.lessThan(QScriptValue()), false);
3185
3186 QScriptValue str2 = QScriptValue("123");
3187 QCOMPARE(str2.lessThan(QScriptValue("124")), true);
3188 QCOMPARE(str2.lessThan(QScriptValue("122")), false);
3189 QCOMPARE(str2.lessThan(QScriptValue("123")), false);
3190 QCOMPARE(str2.lessThan(QScriptValue(124)), true);
3191 QCOMPARE(str2.lessThan(QScriptValue(122)), false);
3192 QCOMPARE(str2.lessThan(QScriptValue(123)), false);
3193 QCOMPARE(str2.lessThan(str), false);
3194 QCOMPARE(str2.lessThan(QScriptValue()), false);
3195
3196 QScriptValue obj1 = eng.newObject();
3197 QScriptValue obj2 = eng.newObject();
3198 QCOMPARE(obj1.lessThan(obj2), false);
3199 QCOMPARE(obj2.lessThan(obj1), false);
3200 QCOMPARE(obj1.lessThan(obj1), false);
3201 QCOMPARE(obj2.lessThan(obj2), false);
3202
3203 QScriptValue date1 = eng.newDate(value: QDateTime(QDate(2000, 1, 1)));
3204 QScriptValue date2 = eng.newDate(value: QDateTime(QDate(1999, 1, 1)));
3205 QCOMPARE(date1.lessThan(date2), false);
3206 QCOMPARE(date2.lessThan(date1), true);
3207 QCOMPARE(date1.lessThan(date1), false);
3208 QCOMPARE(date2.lessThan(date2), false);
3209 QCOMPARE(date1.lessThan(QScriptValue()), false);
3210
3211 QCOMPARE(QScriptValue().lessThan(date2), false);
3212
3213 QScriptEngine otherEngine;
3214 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::lessThan: "
3215 "cannot compare to a value created in "
3216 "a different engine");
3217 QCOMPARE(date1.lessThan(QScriptValue(&otherEngine, 123)), false);
3218}
3219
3220void tst_QScriptValue::equals()
3221{
3222 QScriptEngine eng;
3223
3224 QVERIFY(QScriptValue().equals(QScriptValue()));
3225
3226 QScriptValue num = QScriptValue(&eng, 123);
3227 QCOMPARE(num.equals(QScriptValue(&eng, 123)), true);
3228 QCOMPARE(num.equals(QScriptValue(&eng, 321)), false);
3229 QCOMPARE(num.equals(QScriptValue(&eng, "123")), true);
3230 QCOMPARE(num.equals(QScriptValue(&eng, "321")), false);
3231 QCOMPARE(num.equals(QScriptValue(&eng, 123).toObject()), true);
3232 QCOMPARE(num.equals(QScriptValue(&eng, 321).toObject()), false);
3233 QCOMPARE(num.equals(QScriptValue(&eng, "123").toObject()), true);
3234 QCOMPARE(num.equals(QScriptValue(&eng, "321").toObject()), false);
3235 QVERIFY(num.toObject().equals(num));
3236 QCOMPARE(num.equals(QScriptValue()), false);
3237
3238 QScriptValue str = QScriptValue(&eng, "123");
3239 QCOMPARE(str.equals(QScriptValue(&eng, "123")), true);
3240 QCOMPARE(str.equals(QScriptValue(&eng, "321")), false);
3241 QCOMPARE(str.equals(QScriptValue(&eng, 123)), true);
3242 QCOMPARE(str.equals(QScriptValue(&eng, 321)), false);
3243 QCOMPARE(str.equals(QScriptValue(&eng, "123").toObject()), true);
3244 QCOMPARE(str.equals(QScriptValue(&eng, "321").toObject()), false);
3245 QCOMPARE(str.equals(QScriptValue(&eng, 123).toObject()), true);
3246 QCOMPARE(str.equals(QScriptValue(&eng, 321).toObject()), false);
3247 QVERIFY(str.toObject().equals(str));
3248 QCOMPARE(str.equals(QScriptValue()), false);
3249
3250 QScriptValue num2 = QScriptValue(123);
3251 QCOMPARE(num2.equals(QScriptValue(123)), true);
3252 QCOMPARE(num2.equals(QScriptValue(321)), false);
3253 QCOMPARE(num2.equals(QScriptValue("123")), true);
3254 QCOMPARE(num2.equals(QScriptValue("321")), false);
3255 QCOMPARE(num2.equals(QScriptValue()), false);
3256
3257 QScriptValue str2 = QScriptValue("123");
3258 QCOMPARE(str2.equals(QScriptValue("123")), true);
3259 QCOMPARE(str2.equals(QScriptValue("321")), false);
3260 QCOMPARE(str2.equals(QScriptValue(123)), true);
3261 QCOMPARE(str2.equals(QScriptValue(321)), false);
3262 QCOMPARE(str2.equals(QScriptValue()), false);
3263
3264 QScriptValue date1 = eng.newDate(value: QDateTime(QDate(2000, 1, 1)));
3265 QScriptValue date2 = eng.newDate(value: QDateTime(QDate(1999, 1, 1)));
3266 QCOMPARE(date1.equals(date2), false);
3267 QCOMPARE(date1.equals(date1), true);
3268 QCOMPARE(date2.equals(date2), true);
3269
3270 QScriptValue undefined = eng.undefinedValue();
3271 QScriptValue null = eng.nullValue();
3272 QCOMPARE(undefined.equals(undefined), true);
3273 QCOMPARE(null.equals(null), true);
3274 QCOMPARE(undefined.equals(null), true);
3275 QCOMPARE(null.equals(undefined), true);
3276 QCOMPARE(undefined.equals(QScriptValue()), false);
3277 QCOMPARE(null.equals(QScriptValue()), false);
3278 QVERIFY(!null.equals(num));
3279 QVERIFY(!undefined.equals(num));
3280
3281 QScriptValue sant = QScriptValue(&eng, true);
3282 QVERIFY(sant.equals(QScriptValue(&eng, 1)));
3283 QVERIFY(sant.equals(QScriptValue(&eng, "1")));
3284 QVERIFY(sant.equals(sant));
3285 QVERIFY(sant.equals(QScriptValue(&eng, 1).toObject()));
3286 QVERIFY(sant.equals(QScriptValue(&eng, "1").toObject()));
3287 QVERIFY(sant.equals(sant.toObject()));
3288 QVERIFY(sant.toObject().equals(sant));
3289 QVERIFY(!sant.equals(QScriptValue(&eng, 0)));
3290 QVERIFY(!sant.equals(undefined));
3291 QVERIFY(!sant.equals(null));
3292
3293 QScriptValue falskt = QScriptValue(&eng, false);
3294 QVERIFY(falskt.equals(QScriptValue(&eng, 0)));
3295 QVERIFY(falskt.equals(QScriptValue(&eng, "0")));
3296 QVERIFY(falskt.equals(falskt));
3297 QVERIFY(falskt.equals(QScriptValue(&eng, 0).toObject()));
3298 QVERIFY(falskt.equals(QScriptValue(&eng, "0").toObject()));
3299 QVERIFY(falskt.equals(falskt.toObject()));
3300 QVERIFY(falskt.toObject().equals(falskt));
3301 QVERIFY(!falskt.equals(sant));
3302 QVERIFY(!falskt.equals(undefined));
3303 QVERIFY(!falskt.equals(null));
3304
3305 QScriptValue obj1 = eng.newObject();
3306 QScriptValue obj2 = eng.newObject();
3307 QCOMPARE(obj1.equals(obj2), false);
3308 QCOMPARE(obj2.equals(obj1), false);
3309 QCOMPARE(obj1.equals(obj1), true);
3310 QCOMPARE(obj2.equals(obj2), true);
3311
3312 QScriptValue qobj1 = eng.newQObject(object: this);
3313 QScriptValue qobj2 = eng.newQObject(object: this);
3314 QScriptValue qobj3 = eng.newQObject(object: 0);
3315 QScriptValue qobj4 = eng.newQObject(object: new QObject(), ownership: QScriptEngine::ScriptOwnership);
3316 QVERIFY(qobj1.equals(qobj2)); // compares the QObject pointers
3317 QVERIFY(!qobj2.equals(qobj4)); // compares the QObject pointers
3318 QVERIFY(!qobj2.equals(obj2)); // compares the QObject pointers
3319
3320 QScriptValue compareFun = eng.evaluate(program: "(function(a, b) { return a == b; })");
3321 QVERIFY(compareFun.isFunction());
3322 {
3323 QScriptValue ret = compareFun.call(thisObject: QScriptValue(), args: QScriptValueList() << qobj1 << qobj2);
3324 QVERIFY(ret.isBool());
3325 QVERIFY(ret.toBool());
3326 ret = compareFun.call(thisObject: QScriptValue(), args: QScriptValueList() << qobj1 << qobj3);
3327 QVERIFY(ret.isBool());
3328 QVERIFY(!ret.toBool());
3329 ret = compareFun.call(thisObject: QScriptValue(), args: QScriptValueList() << qobj1 << qobj4);
3330 QVERIFY(ret.isBool());
3331 QVERIFY(!ret.toBool());
3332 ret = compareFun.call(thisObject: QScriptValue(), args: QScriptValueList() << qobj1 << obj1);
3333 QVERIFY(ret.isBool());
3334 QVERIFY(!ret.toBool());
3335 }
3336
3337 {
3338 QScriptValue var1 = eng.newVariant(value: QVariant(false));
3339 QScriptValue var2 = eng.newVariant(value: QVariant(false));
3340 QVERIFY(var1.equals(var2));
3341 {
3342 QScriptValue ret = compareFun.call(thisObject: QScriptValue(), args: QScriptValueList() << var1 << var2);
3343 QVERIFY(ret.isBool());
3344 QVERIFY(ret.toBool());
3345 }
3346 }
3347 {
3348 QScriptValue var1 = eng.newVariant(value: QVariant(false));
3349 QScriptValue var2 = eng.newVariant(value: QVariant(0));
3350 // QVariant::operator==() performs type conversion
3351 QVERIFY(var1.equals(var2));
3352 }
3353 {
3354 QScriptValue var1 = eng.newVariant(value: QVariant(QStringList() << "a"));
3355 QScriptValue var2 = eng.newVariant(value: QVariant(QStringList() << "a"));
3356 QVERIFY(var1.equals(var2));
3357 }
3358 {
3359 QScriptValue var1 = eng.newVariant(value: QVariant(QStringList() << "a"));
3360 QScriptValue var2 = eng.newVariant(value: QVariant(QStringList() << "b"));
3361 QVERIFY(!var1.equals(var2));
3362 }
3363 {
3364 QScriptValue var1 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3365 QScriptValue var2 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3366 QVERIFY(var1.equals(var2));
3367 }
3368 {
3369 QScriptValue var1 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3370 QScriptValue var2 = eng.newVariant(value: QVariant(QPoint(3, 4)));
3371 QVERIFY(!var1.equals(var2));
3372 }
3373 {
3374 QScriptValue var1 = eng.newVariant(value: QVariant(int(1)));
3375 QScriptValue var2 = eng.newVariant(value: QVariant(double(1)));
3376 // QVariant::operator==() performs type conversion
3377 QVERIFY(var1.equals(var2));
3378 }
3379 {
3380 QScriptValue var1 = eng.newVariant(value: QVariant(QString::fromLatin1(str: "123")));
3381 QScriptValue var2 = eng.newVariant(value: QVariant(double(123)));
3382 QScriptValue var3(QString::fromLatin1(str: "123"));
3383 QScriptValue var4(123);
3384
3385 QVERIFY(var1.equals(var1));
3386 QVERIFY(var1.equals(var2));
3387 QVERIFY(var1.equals(var3));
3388 QVERIFY(var1.equals(var4));
3389
3390 QVERIFY(var2.equals(var1));
3391 QVERIFY(var2.equals(var2));
3392 QVERIFY(var2.equals(var3));
3393 QVERIFY(var2.equals(var4));
3394
3395 QVERIFY(var3.equals(var1));
3396 QVERIFY(var3.equals(var2));
3397 QVERIFY(var3.equals(var3));
3398 QVERIFY(var3.equals(var4));
3399
3400 QVERIFY(var4.equals(var1));
3401 QVERIFY(var4.equals(var2));
3402 QVERIFY(var4.equals(var3));
3403 QVERIFY(var4.equals(var4));
3404 }
3405
3406 QScriptEngine otherEngine;
3407 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::equals: "
3408 "cannot compare to a value created in "
3409 "a different engine");
3410 QCOMPARE(date1.equals(QScriptValue(&otherEngine, 123)), false);
3411}
3412
3413void tst_QScriptValue::strictlyEquals()
3414{
3415 QScriptEngine eng;
3416
3417 QVERIFY(QScriptValue().strictlyEquals(QScriptValue()));
3418
3419 QScriptValue num = QScriptValue(&eng, 123);
3420 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, 123)), true);
3421 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, 321)), false);
3422 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, "123")), false);
3423 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, "321")), false);
3424 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, 123).toObject()), false);
3425 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, 321).toObject()), false);
3426 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, "123").toObject()), false);
3427 QCOMPARE(num.strictlyEquals(QScriptValue(&eng, "321").toObject()), false);
3428 QVERIFY(!num.toObject().strictlyEquals(num));
3429 QVERIFY(!num.strictlyEquals(QScriptValue()));
3430 QVERIFY(!QScriptValue().strictlyEquals(num));
3431
3432 QScriptValue str = QScriptValue(&eng, "123");
3433 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, "123")), true);
3434 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, "321")), false);
3435 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, 123)), false);
3436 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, 321)), false);
3437 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, "123").toObject()), false);
3438 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, "321").toObject()), false);
3439 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, 123).toObject()), false);
3440 QCOMPARE(str.strictlyEquals(QScriptValue(&eng, 321).toObject()), false);
3441 QVERIFY(!str.toObject().strictlyEquals(str));
3442 QVERIFY(!str.strictlyEquals(QScriptValue()));
3443
3444 QScriptValue num2 = QScriptValue(123);
3445 QCOMPARE(num2.strictlyEquals(QScriptValue(123)), true);
3446 QCOMPARE(num2.strictlyEquals(QScriptValue(321)), false);
3447 QCOMPARE(num2.strictlyEquals(QScriptValue("123")), false);
3448 QCOMPARE(num2.strictlyEquals(QScriptValue("321")), false);
3449 QVERIFY(!num2.strictlyEquals(QScriptValue()));
3450
3451 QScriptValue str2 = QScriptValue("123");
3452 QCOMPARE(str2.strictlyEquals(QScriptValue("123")), true);
3453 QCOMPARE(str2.strictlyEquals(QScriptValue("321")), false);
3454 QCOMPARE(str2.strictlyEquals(QScriptValue(123)), false);
3455 QCOMPARE(str2.strictlyEquals(QScriptValue(321)), false);
3456 QVERIFY(!str2.strictlyEquals(QScriptValue()));
3457
3458 QScriptValue date1 = eng.newDate(value: QDateTime(QDate(2000, 1, 1)));
3459 QScriptValue date2 = eng.newDate(value: QDateTime(QDate(1999, 1, 1)));
3460 QCOMPARE(date1.strictlyEquals(date2), false);
3461 QCOMPARE(date1.strictlyEquals(date1), true);
3462 QCOMPARE(date2.strictlyEquals(date2), true);
3463 QVERIFY(!date1.strictlyEquals(QScriptValue()));
3464
3465 QScriptValue undefined = eng.undefinedValue();
3466 QScriptValue null = eng.nullValue();
3467 QCOMPARE(undefined.strictlyEquals(undefined), true);
3468 QCOMPARE(null.strictlyEquals(null), true);
3469 QCOMPARE(undefined.strictlyEquals(null), false);
3470 QCOMPARE(null.strictlyEquals(undefined), false);
3471 QVERIFY(!null.strictlyEquals(QScriptValue()));
3472
3473 QScriptValue sant = QScriptValue(&eng, true);
3474 QVERIFY(!sant.strictlyEquals(QScriptValue(&eng, 1)));
3475 QVERIFY(!sant.strictlyEquals(QScriptValue(&eng, "1")));
3476 QVERIFY(sant.strictlyEquals(sant));
3477 QVERIFY(!sant.strictlyEquals(QScriptValue(&eng, 1).toObject()));
3478 QVERIFY(!sant.strictlyEquals(QScriptValue(&eng, "1").toObject()));
3479 QVERIFY(!sant.strictlyEquals(sant.toObject()));
3480 QVERIFY(!sant.toObject().strictlyEquals(sant));
3481 QVERIFY(!sant.strictlyEquals(QScriptValue(&eng, 0)));
3482 QVERIFY(!sant.strictlyEquals(undefined));
3483 QVERIFY(!sant.strictlyEquals(null));
3484 QVERIFY(!sant.strictlyEquals(QScriptValue()));
3485
3486 QScriptValue falskt = QScriptValue(&eng, false);
3487 QVERIFY(!falskt.strictlyEquals(QScriptValue(&eng, 0)));
3488 QVERIFY(!falskt.strictlyEquals(QScriptValue(&eng, "0")));
3489 QVERIFY(falskt.strictlyEquals(falskt));
3490 QVERIFY(!falskt.strictlyEquals(QScriptValue(&eng, 0).toObject()));
3491 QVERIFY(!falskt.strictlyEquals(QScriptValue(&eng, "0").toObject()));
3492 QVERIFY(!falskt.strictlyEquals(falskt.toObject()));
3493 QVERIFY(!falskt.toObject().strictlyEquals(falskt));
3494 QVERIFY(!falskt.strictlyEquals(sant));
3495 QVERIFY(!falskt.strictlyEquals(undefined));
3496 QVERIFY(!falskt.strictlyEquals(null));
3497 QVERIFY(!falskt.strictlyEquals(QScriptValue()));
3498
3499 QVERIFY(!QScriptValue(false).strictlyEquals(123));
3500 QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).strictlyEquals(123));
3501 QVERIFY(!QScriptValue(QScriptValue::NullValue).strictlyEquals(123));
3502 QVERIFY(!QScriptValue(false).strictlyEquals("ciao"));
3503 QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).strictlyEquals("ciao"));
3504 QVERIFY(!QScriptValue(QScriptValue::NullValue).strictlyEquals("ciao"));
3505 QVERIFY(QScriptValue(&eng, "ciao").strictlyEquals("ciao"));
3506 QVERIFY(QScriptValue("ciao").strictlyEquals(QScriptValue(&eng, "ciao")));
3507 QVERIFY(!QScriptValue("ciao").strictlyEquals(123));
3508 QVERIFY(!QScriptValue("ciao").strictlyEquals(QScriptValue(&eng, 123)));
3509 QVERIFY(!QScriptValue(123).strictlyEquals("ciao"));
3510 QVERIFY(!QScriptValue(123).strictlyEquals(QScriptValue(&eng, "ciao")));
3511 QVERIFY(!QScriptValue(&eng, 123).strictlyEquals("ciao"));
3512
3513 QScriptValue obj1 = eng.newObject();
3514 QScriptValue obj2 = eng.newObject();
3515 QCOMPARE(obj1.strictlyEquals(obj2), false);
3516 QCOMPARE(obj2.strictlyEquals(obj1), false);
3517 QCOMPARE(obj1.strictlyEquals(obj1), true);
3518 QCOMPARE(obj2.strictlyEquals(obj2), true);
3519 QVERIFY(!obj1.strictlyEquals(QScriptValue()));
3520
3521 QScriptValue qobj1 = eng.newQObject(object: this);
3522 QScriptValue qobj2 = eng.newQObject(object: this);
3523 QVERIFY(!qobj1.strictlyEquals(qobj2));
3524
3525 {
3526 QScriptValue var1 = eng.newVariant(value: QVariant(false));
3527 QScriptValue var2 = eng.newVariant(value: QVariant(false));
3528 QVERIFY(!var1.strictlyEquals(var2));
3529 QVERIFY(!var1.strictlyEquals(QScriptValue()));
3530 }
3531 {
3532 QScriptValue var1 = eng.newVariant(value: QVariant(false));
3533 QScriptValue var2 = eng.newVariant(value: QVariant(0));
3534 QVERIFY(!var1.strictlyEquals(var2));
3535 }
3536 {
3537 QScriptValue var1 = eng.newVariant(value: QVariant(QStringList() << "a"));
3538 QScriptValue var2 = eng.newVariant(value: QVariant(QStringList() << "a"));
3539 QVERIFY(!var1.strictlyEquals(var2));
3540 }
3541 {
3542 QScriptValue var1 = eng.newVariant(value: QVariant(QStringList() << "a"));
3543 QScriptValue var2 = eng.newVariant(value: QVariant(QStringList() << "b"));
3544 QVERIFY(!var1.strictlyEquals(var2));
3545 }
3546 {
3547 QScriptValue var1 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3548 QScriptValue var2 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3549 QVERIFY(!var1.strictlyEquals(var2));
3550 }
3551 {
3552 QScriptValue var1 = eng.newVariant(value: QVariant(QPoint(1, 2)));
3553 QScriptValue var2 = eng.newVariant(value: QVariant(QPoint(3, 4)));
3554 QVERIFY(!var1.strictlyEquals(var2));
3555 }
3556
3557 QScriptEngine otherEngine;
3558 QTest::ignoreMessage(type: QtWarningMsg, message: "QScriptValue::strictlyEquals: "
3559 "cannot compare to a value created in "
3560 "a different engine");
3561 QCOMPARE(date1.strictlyEquals(QScriptValue(&otherEngine, 123)), false);
3562}
3563
3564Q_DECLARE_METATYPE(int*)
3565Q_DECLARE_METATYPE(double*)
3566Q_DECLARE_METATYPE(QColor*)
3567Q_DECLARE_METATYPE(QBrush*)
3568
3569void tst_QScriptValue::castToPointer()
3570{
3571 QScriptEngine eng;
3572 {
3573 QScriptValue v = eng.newVariant(value: int(123));
3574 int *ip = qscriptvalue_cast<int*>(value: v);
3575 QVERIFY(ip != 0);
3576 QCOMPARE(*ip, 123);
3577 *ip = 456;
3578 QCOMPARE(qscriptvalue_cast<int>(v), 456);
3579
3580 double *dp = qscriptvalue_cast<double*>(value: v);
3581 QVERIFY(dp == 0);
3582
3583 QScriptValue v2 = eng.newVariant(value: QVariant::fromValue(value: ip));
3584 QCOMPARE(qscriptvalue_cast<int*>(v2), ip);
3585 }
3586 {
3587 QColor c(123, 210, 231);
3588 QScriptValue v = eng.newVariant(value: c);
3589 QColor *cp = qscriptvalue_cast<QColor*>(value: v);
3590 QVERIFY(cp != 0);
3591 QCOMPARE(*cp, c);
3592
3593 QBrush *bp = qscriptvalue_cast<QBrush*>(value: v);
3594 QVERIFY(bp == 0);
3595
3596 QScriptValue v2 = eng.newVariant(value: QVariant::fromValue(value: cp));
3597 QCOMPARE(qscriptvalue_cast<QColor*>(v2), cp);
3598 }
3599}
3600
3601void tst_QScriptValue::prettyPrinter_data()
3602{
3603 QTest::addColumn<QString>(name: "function");
3604 QTest::addColumn<QString>(name: "expected");
3605 QTest::newRow(dataTag: "function() { }") << QString("function() { }") << QString("function () { }");
3606 QTest::newRow(dataTag: "function foo() { }") << QString("(function foo() { })") << QString("function foo() { }");
3607 QTest::newRow(dataTag: "function foo(bar) { }") << QString("(function foo(bar) { })") << QString("function foo(bar) { }");
3608 QTest::newRow(dataTag: "function foo(bar, baz) { }") << QString("(function foo(bar, baz) { })") << QString("function foo(bar, baz) { }");
3609 QTest::newRow(dataTag: "this") << QString("function() { this; }") << QString("function () { this; }");
3610 QTest::newRow(dataTag: "identifier") << QString("function(a) { a; }") << QString("function (a) { a; }");
3611 QTest::newRow(dataTag: "null") << QString("function() { null; }") << QString("function () { null; }");
3612 QTest::newRow(dataTag: "true") << QString("function() { true; }") << QString("function () { true; }");
3613 QTest::newRow(dataTag: "false") << QString("function() { false; }") << QString("function () { false; }");
3614 QTest::newRow(dataTag: "string") << QString("function() { 'test'; }") << QString("function () { \'test\'; }");
3615 QTest::newRow(dataTag: "string") << QString("function() { \"test\"; }") << QString("function () { \"test\"; }");
3616 QTest::newRow(dataTag: "number") << QString("function() { 123; }") << QString("function () { 123; }");
3617 QTest::newRow(dataTag: "number") << QString("function() { 123.456; }") << QString("function () { 123.456; }");
3618 QTest::newRow(dataTag: "regexp") << QString("function() { /hello/; }") << QString("function () { /hello/; }");
3619 QTest::newRow(dataTag: "regexp") << QString("function() { /hello/gim; }") << QString("function () { /hello/gim; }");
3620 QTest::newRow(dataTag: "array") << QString("function() { []; }") << QString("function () { []; }");
3621 QTest::newRow(dataTag: "array") << QString("function() { [10]; }") << QString("function () { [10]; }");
3622 QTest::newRow(dataTag: "array") << QString("function() { [10, 20, 30]; }") << QString("function () { [10, 20, 30]; }");
3623 QTest::newRow(dataTag: "array") << QString("function() { [10, 20, , 40]; }") << QString("function () { [10, 20, , 40]; }");
3624 QTest::newRow(dataTag: "array") << QString("function() { [,]; }") << QString("function () { [,]; }");
3625 QTest::newRow(dataTag: "array") << QString("function() { [, 10]; }") << QString("function () { [, 10]; }");
3626 QTest::newRow(dataTag: "array") << QString("function() { [, 10, ]; }") << QString("function () { [, 10, ]; }");
3627 QTest::newRow(dataTag: "array") << QString("function() { [, 10, ,]; }") << QString("function () { [, 10, ,]; }");
3628 QTest::newRow(dataTag: "array") << QString("function() { [[10], [20]]; }") << QString("function () { [[10], [20]]; }");
3629 QTest::newRow(dataTag: "member") << QString("function() { a.b; }") << QString("function () { a.b; }");
3630 QTest::newRow(dataTag: "member") << QString("function() { a.b.c; }") << QString("function () { a.b.c; }");
3631 QTest::newRow(dataTag: "call") << QString("function() { f(); }") << QString("function () { f(); }");
3632 QTest::newRow(dataTag: "call") << QString("function() { f(a); }") << QString("function () { f(a); }");
3633 QTest::newRow(dataTag: "call") << QString("function() { f(a, b); }") << QString("function () { f(a, b); }");
3634 QTest::newRow(dataTag: "new") << QString("function() { new C(); }") << QString("function () { new C(); }");
3635 QTest::newRow(dataTag: "new") << QString("function() { new C(a); }") << QString("function () { new C(a); }");
3636 QTest::newRow(dataTag: "new") << QString("function() { new C(a, b); }") << QString("function () { new C(a, b); }");
3637 QTest::newRow(dataTag: "++") << QString("function() { a++; }") << QString("function () { a++; }");
3638 QTest::newRow(dataTag: "++") << QString("function() { ++a; }") << QString("function () { ++a; }");
3639 QTest::newRow(dataTag: "--") << QString("function() { a--; }") << QString("function () { a--; }");
3640 QTest::newRow(dataTag: "--") << QString("function() { --a; }") << QString("function () { --a; }");
3641 QTest::newRow(dataTag: "delete") << QString("function() { delete a; }") << QString("function () { delete a; }");
3642 QTest::newRow(dataTag: "void") << QString("function() { void a; }") << QString("function () { void a; }");
3643 QTest::newRow(dataTag: "typeof") << QString("function() { typeof a; }") << QString("function () { typeof a; }");
3644 QTest::newRow(dataTag: "+") << QString("function() { +a; }") << QString("function () { +a; }");
3645 QTest::newRow(dataTag: "-") << QString("function() { -a; }") << QString("function () { -a; }");
3646 QTest::newRow(dataTag: "~") << QString("function() { ~a; }") << QString("function () { ~a; }");
3647 QTest::newRow(dataTag: "!") << QString("function() { !a; }") << QString("function () { !a; }");
3648 QTest::newRow(dataTag: "+") << QString("function() { a + b; }") << QString("function () { a + b; }");
3649 QTest::newRow(dataTag: "&&") << QString("function() { a && b; }") << QString("function () { a && b; }");
3650 QTest::newRow(dataTag: "&=") << QString("function() { a &= b; }") << QString("function () { a &= b; }");
3651 QTest::newRow(dataTag: "=") << QString("function() { a = b; }") << QString("function () { a = b; }");
3652 QTest::newRow(dataTag: "&") << QString("function() { a & b; }") << QString("function () { a & b; }");
3653 QTest::newRow(dataTag: "|") << QString("function() { a | b; }") << QString("function () { a | b; }");
3654 QTest::newRow(dataTag: "^") << QString("function() { a ^ b; }") << QString("function () { a ^ b; }");
3655 QTest::newRow(dataTag: "-=") << QString("function() { a -= b; }") << QString("function () { a -= b; }");
3656 QTest::newRow(dataTag: "/") << QString("function() { a / b; }") << QString("function () { a / b; }");
3657 QTest::newRow(dataTag: "/=") << QString("function() { a /= b; }") << QString("function () { a /= b; }");
3658 QTest::newRow(dataTag: "==") << QString("function() { a == b; }") << QString("function () { a == b; }");
3659 QTest::newRow(dataTag: ">=") << QString("function() { a >= b; }") << QString("function () { a >= b; }");
3660 QTest::newRow(dataTag: ">") << QString("function() { a > b; }") << QString("function () { a > b; }");
3661 QTest::newRow(dataTag: "in") << QString("function() { a in b; }") << QString("function () { a in b; }");
3662 QTest::newRow(dataTag: "+=") << QString("function() { a += b; }") << QString("function () { a += b; }");
3663 QTest::newRow(dataTag: "instanceof") << QString("function() { a instanceof b; }") << QString("function () { a instanceof b; }");
3664 QTest::newRow(dataTag: "<=") << QString("function() { a <= b; }") << QString("function () { a <= b; }");
3665 QTest::newRow(dataTag: "<<") << QString("function() { a << b; }") << QString("function () { a << b; }");
3666 QTest::newRow(dataTag: "<<=") << QString("function() { a <<= b; }") << QString("function () { a <<= b; }");
3667 QTest::newRow(dataTag: "<") << QString("function() { a < b; }") << QString("function () { a < b; }");
3668 QTest::newRow(dataTag: "%") << QString("function() { a % b; }") << QString("function () { a % b; }");
3669 QTest::newRow(dataTag: "%=") << QString("function() { a %= b; }") << QString("function () { a %= b; }");
3670 QTest::newRow(dataTag: "*") << QString("function() { a * b; }") << QString("function () { a * b; }");
3671 QTest::newRow(dataTag: "*=") << QString("function() { a *= b; }") << QString("function () { a *= b; }");
3672 QTest::newRow(dataTag: "!=") << QString("function() { a != b; }") << QString("function () { a != b; }");
3673 QTest::newRow(dataTag: "||") << QString("function() { a || b; }") << QString("function () { a || b; }");
3674 QTest::newRow(dataTag: "|=") << QString("function() { a |= b; }") << QString("function () { a |= b; }");
3675 QTest::newRow(dataTag: ">>") << QString("function() { a >> b; }") << QString("function () { a >> b; }");
3676 QTest::newRow(dataTag: ">>=") << QString("function() { a >>= b; }") << QString("function () { a >>= b; }");
3677 QTest::newRow(dataTag: "===") << QString("function() { a === b; }") << QString("function () { a === b; }");
3678 QTest::newRow(dataTag: "!==") << QString("function() { a !== b; }") << QString("function () { a !== b; }");
3679 QTest::newRow(dataTag: "-") << QString("function() { a - b; }") << QString("function () { a - b; }");
3680 QTest::newRow(dataTag: ">>>") << QString("function() { a >>> b; }") << QString("function () { a >>> b; }");
3681 QTest::newRow(dataTag: ">>>=") << QString("function() { a >>>= b; }") << QString("function () { a >>>= b; }");
3682 QTest::newRow(dataTag: "^=") << QString("function() { a ^= b; }") << QString("function () { a ^= b; }");
3683 QTest::newRow(dataTag: "? :") << QString("function() { a ? b : c; }") << QString("function () { a ? b : c; }");
3684 QTest::newRow(dataTag: "a; b; c") << QString("function() { a; b; c; }") << QString("function () { a; b; c; }");
3685 QTest::newRow(dataTag: "var a;") << QString("function() { var a; }") << QString("function () { var a; }");
3686 QTest::newRow(dataTag: "var a, b;") << QString("function() { var a, b; }") << QString("function () { var a, b; }");
3687 QTest::newRow(dataTag: "var a = 10;") << QString("function() { var a = 10; }") << QString("function () { var a = 10; }");
3688 QTest::newRow(dataTag: "var a, b = 20;") << QString("function() { var a, b = 20; }") << QString("function () { var a, b = 20; }");
3689 QTest::newRow(dataTag: "var a = 10, b = 20;") << QString("function() { var a = 10, b = 20; }") << QString("function () { var a = 10, b = 20; }");
3690 QTest::newRow(dataTag: "if") << QString("function() { if (a) b; }") << QString("function () { if (a) b; }");
3691 QTest::newRow(dataTag: "if") << QString("function() { if (a) { b; c; } }") << QString("function () { if (a) { b; c; } }");
3692 QTest::newRow(dataTag: "if-else") << QString("function() { if (a) b; else c; }") << QString("function () { if (a) b; else c; }");
3693 QTest::newRow(dataTag: "if-else") << QString("function() { if (a) { b; c; } else { d; e; } }") << QString("function () { if (a) { b; c; } else { d; e; } }");
3694 QTest::newRow(dataTag: "do-while") << QString("function() { do { a; } while (b); }") << QString("function () { do { a; } while (b); }");
3695 QTest::newRow(dataTag: "do-while") << QString("function() { do { a; b; c; } while (d); }") << QString("function () { do { a; b; c; } while (d); }");
3696 QTest::newRow(dataTag: "while") << QString("function() { while (a) { b; } }") << QString("function () { while (a) { b; } }");
3697 QTest::newRow(dataTag: "while") << QString("function() { while (a) { b; c; } }") << QString("function () { while (a) { b; c; } }");
3698 QTest::newRow(dataTag: "for") << QString("function() { for (a; b; c) { } }") << QString("function () { for (a; b; c) { } }");
3699 QTest::newRow(dataTag: "for") << QString("function() { for (; a; b) { } }") << QString("function () { for (; a; b) { } }");
3700 QTest::newRow(dataTag: "for") << QString("function() { for (; ; a) { } }") << QString("function () { for (; ; a) { } }");
3701 QTest::newRow(dataTag: "for") << QString("function() { for (; ; ) { } }") << QString("function () { for (; ; ) { } }");
3702 QTest::newRow(dataTag: "for") << QString("function() { for (var a; b; c) { } }") << QString("function () { for (var a; b; c) { } }");
3703 QTest::newRow(dataTag: "for") << QString("function() { for (var a, b, c; d; e) { } }") << QString("function () { for (var a, b, c; d; e) { } }");
3704 QTest::newRow(dataTag: "continue") << QString("function() { for (; ; ) { continue; } }") << QString("function () { for (; ; ) { continue; } }");
3705 QTest::newRow(dataTag: "continue") << QString("function() { for (; ; ) { continue label; } }") << QString("function () { for (; ; ) { continue label; } }");
3706 QTest::newRow(dataTag: "break") << QString("function() { for (; ; ) { break; } }") << QString("function () { for (; ; ) { break; } }");
3707 QTest::newRow(dataTag: "break") << QString("function() { for (; ; ) { break label; } }") << QString("function () { for (; ; ) { break label; } }");
3708 QTest::newRow(dataTag: "return") << QString("function() { return; }") << QString("function () { return; }");
3709 QTest::newRow(dataTag: "return") << QString("function() { return 10; }") << QString("function () { return 10; }");
3710 QTest::newRow(dataTag: "with") << QString("function() { with (a) { b; } }") << QString("function () { with (a) { b; } }");
3711 QTest::newRow(dataTag: "with") << QString("function() { with (a) { b; c; } }") << QString("function () { with (a) { b; c; } }");
3712 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { } }") << QString("function () { switch (a) { } }");
3713 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: ; } }") << QString("function () { switch (a) { case 1: ; } }");
3714 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: b; break; } }") << QString("function () { switch (a) { case 1: b; break; } }");
3715 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: b; break; case 2: break; } }") << QString("function () { switch (a) { case 1: b; break; case 2: break; } }");
3716 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: case 2: ; } }") << QString("function () { switch (a) { case 1: case 2: ; } }");
3717 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: default: ; } }") << QString("function () { switch (a) { case 1: default: ; } }");
3718 QTest::newRow(dataTag: "switch") << QString("function() { switch (a) { case 1: default: ; case 3: ; } }") << QString("function () { switch (a) { case 1: default: ; case 3: ; } }");
3719 QTest::newRow(dataTag: "label") << QString("function() { a: b; }") << QString("function () { a: b; }");
3720 QTest::newRow(dataTag: "throw") << QString("function() { throw a; }") << QString("function () { throw a; }");
3721 QTest::newRow(dataTag: "try-catch") << QString("function() { try { a; } catch (e) { b; } }") << QString("function () { try { a; } catch (e) { b; } }");
3722 QTest::newRow(dataTag: "try-finally") << QString("function() { try { a; } finally { b; } }") << QString("function () { try { a; } finally { b; } }");
3723 QTest::newRow(dataTag: "try-catch-finally") << QString("function() { try { a; } catch (e) { b; } finally { c; } }") << QString("function () { try { a; } catch (e) { b; } finally { c; } }");
3724 QTest::newRow(dataTag: "a + b + c + d") << QString("function() { a + b + c + d; }") << QString("function () { a + b + c + d; }");
3725 QTest::newRow(dataTag: "a + b - c") << QString("function() { a + b - c; }") << QString("function () { a + b - c; }");
3726 QTest::newRow(dataTag: "a + -b") << QString("function() { a + -b; }") << QString("function () { a + -b; }");
3727 QTest::newRow(dataTag: "a + ~b") << QString("function() { a + ~b; }") << QString("function () { a + ~b; }");
3728 QTest::newRow(dataTag: "a + !b") << QString("function() { a + !b; }") << QString("function () { a + !b; }");
3729 QTest::newRow(dataTag: "a + +b") << QString("function() { a + +b; }") << QString("function () { a + +b; }");
3730 QTest::newRow(dataTag: "(a + b) - c") << QString("function() { (a + b) - c; }") << QString("function () { (a + b) - c; }");
3731 QTest::newRow(dataTag: "(a - b + c") << QString("function() { a - b + c; }") << QString("function () { a - b + c; }");
3732 QTest::newRow(dataTag: "(a - (b + c)") << QString("function() { a - (b + c); }") << QString("function () { a - (b + c); }");
3733 QTest::newRow(dataTag: "a + -(b + c)") << QString("function() { a + -(b + c); }") << QString("function () { a + -(b + c); }");
3734 QTest::newRow(dataTag: "a + ~(b + c)") << QString("function() { a + ~(b + c); }") << QString("function () { a + ~(b + c); }");
3735 QTest::newRow(dataTag: "a + !(b + c)") << QString("function() { a + !(b + c); }") << QString("function () { a + !(b + c); }");
3736 QTest::newRow(dataTag: "a + +(b + c)") << QString("function() { a + +(b + c); }") << QString("function () { a + +(b + c); }");
3737 QTest::newRow(dataTag: "a + b * c") << QString("function() { a + b * c; }") << QString("function () { a + b * c; }");
3738 QTest::newRow(dataTag: "(a + b) * c") << QString("function() { (a + b) * c; }") << QString("function () { (a + b) * c; }");
3739 QTest::newRow(dataTag: "(a + b) * (c + d)") << QString("function() { (a + b) * (c + d); }") << QString("function () { (a + b) * (c + d); }");
3740 QTest::newRow(dataTag: "a + (b * c)") << QString("function() { a + (b * c); }") << QString("function () { a + (b * c); }");
3741 QTest::newRow(dataTag: "a + (b / c)") << QString("function() { a + (b / c); }") << QString("function () { a + (b / c); }");
3742 QTest::newRow(dataTag: "(a / b) * c") << QString("function() { (a / b) * c; }") << QString("function () { (a / b) * c; }");
3743 QTest::newRow(dataTag: "a / (b * c)") << QString("function() { a / (b * c); }") << QString("function () { a / (b * c); }");
3744 QTest::newRow(dataTag: "a / (b % c)") << QString("function() { a / (b % c); }") << QString("function () { a / (b % c); }");
3745 QTest::newRow(dataTag: "a && b || c") << QString("function() { a && b || c; }") << QString("function () { a && b || c; }");
3746 QTest::newRow(dataTag: "a && (b || c)") << QString("function() { a && (b || c); }") << QString("function () { a && (b || c); }");
3747 QTest::newRow(dataTag: "a & b | c") << QString("function() { a & b | c; }") << QString("function () { a & b | c; }");
3748 QTest::newRow(dataTag: "a & (b | c)") << QString("function() { a & (b | c); }") << QString("function () { a & (b | c); }");
3749 QTest::newRow(dataTag: "a & b | c ^ d") << QString("function() { a & b | c ^ d; }") << QString("function () { a & b | c ^ d; }");
3750 QTest::newRow(dataTag: "a & (b | c ^ d)") << QString("function() { a & (b | c ^ d); }") << QString("function () { a & (b | c ^ d); }");
3751 QTest::newRow(dataTag: "(a & b | c) ^ d") << QString("function() { (a & b | c) ^ d; }") << QString("function () { (a & b | c) ^ d; }");
3752 QTest::newRow(dataTag: "a << b + c") << QString("function() { a << b + c; }") << QString("function () { a << b + c; }");
3753 QTest::newRow(dataTag: "(a << b) + c") << QString("function() { (a << b) + c; }") << QString("function () { (a << b) + c; }");
3754 QTest::newRow(dataTag: "a >> b + c") << QString("function() { a >> b + c; }") << QString("function () { a >> b + c; }");
3755 QTest::newRow(dataTag: "(a >> b) + c") << QString("function() { (a >> b) + c; }") << QString("function () { (a >> b) + c; }");
3756 QTest::newRow(dataTag: "a >>> b + c") << QString("function() { a >>> b + c; }") << QString("function () { a >>> b + c; }");
3757 QTest::newRow(dataTag: "(a >>> b) + c") << QString("function() { (a >>> b) + c; }") << QString("function () { (a >>> b) + c; }");
3758 QTest::newRow(dataTag: "a == b || c != d") << QString("function() { a == b || c != d; }") << QString("function () { a == b || c != d; }");
3759 QTest::newRow(dataTag: "a == (b || c != d)") << QString("function() { a == (b || c != d); }") << QString("function () { a == (b || c != d); }");
3760 QTest::newRow(dataTag: "a === b || c !== d") << QString("function() { a === b || c !== d; }") << QString("function () { a === b || c !== d; }");
3761 QTest::newRow(dataTag: "a === (b || c !== d)") << QString("function() { a === (b || c !== d); }") << QString("function () { a === (b || c !== d); }");
3762 QTest::newRow(dataTag: "a &= b + c") << QString("function() { a &= b + c; }") << QString("function () { a &= b + c; }");
3763 QTest::newRow(dataTag: "debugger") << QString("function() { debugger }") << QString("function () { debugger; }");
3764}
3765
3766void tst_QScriptValue::prettyPrinter()
3767{
3768 QFETCH(QString, function);
3769 QFETCH(QString, expected);
3770 QScriptEngine eng;
3771 QScriptValue val = eng.evaluate(program: "(" + function + ")");
3772 QVERIFY(val.isFunction());
3773 QString actual = val.toString();
3774 int count = qMin(a: actual.size(), b: expected.size());
3775// qDebug() << actual << expected;
3776 for (int i = 0; i < count; ++i) {
3777// qDebug() << i << actual.at(i) << expected.at(i);
3778 QCOMPARE(actual.at(i), expected.at(i));
3779 }
3780 QCOMPARE(actual.size(), expected.size());
3781}
3782
3783void tst_QScriptValue::engineDeleted()
3784{
3785 QScriptEngine *eng = new QScriptEngine;
3786 QScriptValue v1(eng, 123);
3787 QVERIFY(v1.isNumber());
3788 QScriptValue v2(eng, QString("ciao"));
3789 QVERIFY(v2.isString());
3790 QScriptValue v3 = eng->newObject();
3791 QVERIFY(v3.isObject());
3792 QScriptValue v4 = eng->newQObject(object: this);
3793 QVERIFY(v4.isQObject());
3794 QScriptValue v5 = "Hello";
3795 QVERIFY(v2.isString());
3796
3797 delete eng;
3798
3799 QVERIFY(!v1.isValid());
3800 QVERIFY(v1.engine() == 0);
3801 QVERIFY(!v2.isValid());
3802 QVERIFY(v2.engine() == 0);
3803 QVERIFY(!v3.isValid());
3804 QVERIFY(v3.engine() == 0);
3805 QVERIFY(!v4.isValid());
3806 QVERIFY(v4.engine() == 0);
3807 QVERIFY(v5.isValid());
3808 QVERIFY(v5.engine() == 0);
3809
3810 QVERIFY(!v3.property("foo").isValid());
3811}
3812
3813void tst_QScriptValue::valueOfWithClosure()
3814{
3815 QScriptEngine eng;
3816 // valueOf()
3817 {
3818 QScriptValue obj = eng.evaluate(program: "o = {}; (function(foo) { o.valueOf = function() { return foo; } })(123); o");
3819 QVERIFY(obj.isObject());
3820 QCOMPARE(obj.toInt32(), 123);
3821 }
3822 // toString()
3823 {
3824 QScriptValue obj = eng.evaluate(program: "o = {}; (function(foo) { o.toString = function() { return foo; } })('ciao'); o");
3825 QVERIFY(obj.isObject());
3826 QCOMPARE(obj.toString(), QString::fromLatin1("ciao"));
3827 }
3828}
3829
3830void tst_QScriptValue::objectId()
3831{
3832 QCOMPARE(QScriptValue().objectId(), (qint64)-1);
3833 QCOMPARE(QScriptValue(QScriptValue::UndefinedValue).objectId(), (qint64)-1);
3834 QCOMPARE(QScriptValue(QScriptValue::NullValue).objectId(), (qint64)-1);
3835 QCOMPARE(QScriptValue(false).objectId(), (qint64)-1);
3836 QCOMPARE(QScriptValue(123).objectId(), (qint64)-1);
3837 QCOMPARE(QScriptValue(uint(123)).objectId(), (qint64)-1);
3838 QCOMPARE(QScriptValue(123.5).objectId(), (qint64)-1);
3839 QCOMPARE(QScriptValue("ciao").objectId(), (qint64)-1);
3840
3841 QScriptEngine eng;
3842 QScriptValue o1 = eng.newObject();
3843 QVERIFY(o1.objectId() != -1);
3844 QScriptValue o2 = eng.newObject();
3845 QVERIFY(o2.objectId() != -1);
3846 QVERIFY(o1.objectId() != o2.objectId());
3847
3848 QVERIFY(eng.objectById(o1.objectId()).strictlyEquals(o1));
3849 QVERIFY(eng.objectById(o2.objectId()).strictlyEquals(o2));
3850
3851 qint64 globalObjectId = -1;
3852 {
3853 QScriptValue global = eng.globalObject();
3854 globalObjectId = global.objectId();
3855 QVERIFY(globalObjectId != -1);
3856 QVERIFY(eng.objectById(globalObjectId).strictlyEquals(global));
3857 }
3858 QScriptValue obj = eng.objectById(id: globalObjectId);
3859 QVERIFY(obj.isObject());
3860 QVERIFY(obj.strictlyEquals(eng.globalObject()));
3861}
3862
3863void tst_QScriptValue::nestedObjectToVariant_data()
3864{
3865 QTest::addColumn<QString>(name: "program");
3866 QTest::addColumn<QVariant>(name: "expected");
3867
3868 // Array literals
3869 QTest::newRow(dataTag: "[[]]")
3870 << QString::fromLatin1(str: "[[]]")
3871 << QVariant(QVariantList() << (QVariant(QVariantList())));
3872 QTest::newRow(dataTag: "[[123]]")
3873 << QString::fromLatin1(str: "[[123]]")
3874 << QVariant(QVariantList() << (QVariant(QVariantList() << 123)));
3875 QTest::newRow(dataTag: "[[], 123]")
3876 << QString::fromLatin1(str: "[[], 123]")
3877 << QVariant(QVariantList() << QVariant(QVariantList()) << 123);
3878
3879 // Cyclic arrays
3880 QTest::newRow(dataTag: "var a=[]; a.push(a)")
3881 << QString::fromLatin1(str: "var a=[]; a.push(a); a")
3882 << QVariant(QVariantList() << QVariant(QVariantList()));
3883 QTest::newRow(dataTag: "var a=[]; a.push(123, a)")
3884 << QString::fromLatin1(str: "var a=[]; a.push(123, a); a")
3885 << QVariant(QVariantList() << 123 << QVariant(QVariantList()));
3886 QTest::newRow(dataTag: "var a=[]; var b=[]; a.push(b); b.push(a)")
3887 << QString::fromLatin1(str: "var a=[]; var b=[]; a.push(b); b.push(a); a")
3888 << QVariant(QVariantList() << QVariant(QVariantList() << QVariant(QVariantList())));
3889 QTest::newRow(dataTag: "var a=[]; var b=[]; a.push(123, b); b.push(456, a)")
3890 << QString::fromLatin1(str: "var a=[]; var b=[]; a.push(123, b); b.push(456, a); a")
3891 << QVariant(QVariantList() << 123 << QVariant(QVariantList() << 456 << QVariant(QVariantList())));
3892
3893 // Object literals
3894 {
3895 QVariantMap m;
3896 m["a"] = QVariantMap();
3897 QTest::newRow(dataTag: "{ a:{} }")
3898 << QString::fromLatin1(str: "({ a:{} })")
3899 << QVariant(m);
3900 }
3901 {
3902 QVariantMap m, m2;
3903 m2["b"] = 10;
3904 m2["c"] = 20;
3905 m["a"] = m2;
3906 QTest::newRow(dataTag: "{ a:{b:10, c:20} }")
3907 << QString::fromLatin1(str: "({ a:{b:10, c:20} })")
3908 << QVariant(m);
3909 }
3910 {
3911 QVariantMap m;
3912 m["a"] = 10;
3913 m["b"] = QVariantList() << 20 << 30;
3914 QTest::newRow(dataTag: "{ a:10, b:[20, 30]}")
3915 << QString::fromLatin1(str: "({ a:10, b:[20,30]})")
3916 << QVariant(m);
3917 }
3918
3919 // Cyclic objects
3920 {
3921 QVariantMap m;
3922 m["p"] = QVariantMap();
3923 QTest::newRow(dataTag: "var o={}; o.p=o")
3924 << QString::fromLatin1(str: "var o={}; o.p=o; o")
3925 << QVariant(m);
3926 }
3927 {
3928 QVariantMap m;
3929 m["p"] = 123;
3930 m["q"] = QVariantMap();
3931 QTest::newRow(dataTag: "var o={}; o.p=123; o.q=o")
3932 << QString::fromLatin1(str: "var o={}; o.p=123; o.q=o; o")
3933 << QVariant(m);
3934 }
3935}
3936
3937void tst_QScriptValue::nestedObjectToVariant()
3938{
3939 QScriptEngine eng;
3940 QFETCH(QString, program);
3941 QFETCH(QVariant, expected);
3942 QScriptValue o = eng.evaluate(program);
3943 QVERIFY(!o.isError());
3944 QVERIFY(o.isObject());
3945 QCOMPARE(o.toVariant(), expected);
3946}
3947
3948void tst_QScriptValue::propertyFlags_data()
3949{
3950 QTest::addColumn<QString>(name: "program");
3951 QTest::addColumn<uint>(name: "expected");
3952
3953 QTest::newRow(dataTag: "nothing") << "" << 0u;
3954 QTest::newRow(dataTag: "getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QScriptValue::PropertyGetter);
3955 QTest::newRow(dataTag: "setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QScriptValue::PropertySetter);
3956 QTest::newRow(dataTag: "getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n"
3957 "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QScriptValue::PropertySetter|QScriptValue::PropertyGetter);
3958 QTest::newRow(dataTag: "nothing2") << "o.prop = 'nothing'" << 0u;
3959}
3960
3961void tst_QScriptValue::propertyFlags()
3962{
3963 QFETCH(QString, program);
3964 QFETCH(uint, expected);
3965 QScriptEngine eng;
3966 eng.evaluate(program: "o = new Object;");
3967 eng.evaluate(program);
3968 QScriptValue o = eng.evaluate(program: "o");
3969
3970 QCOMPARE(uint(o.propertyFlags("prop")), expected);
3971}
3972
3973
3974QTEST_MAIN(tst_QScriptValue)
3975

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtscript/tests/auto/qscriptvalue/tst_qscriptvalue.cpp