]>
Commit | Line | Data |
---|---|---|
f9bf01c6 A |
1 | /* |
2 | Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) | |
3 | ||
4 | This library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Library General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2 of the License, or (at your option) any later version. | |
8 | ||
9 | This library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Library General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Library General Public License | |
15 | along with this library; see the file COPYING.LIB. If not, write to | |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
17 | Boston, MA 02110-1301, USA. | |
18 | */ | |
19 | ||
20 | #include "qscriptengine.h" | |
21 | #include "qscriptvalue.h" | |
22 | #include <QtTest/qtest.h> | |
23 | ||
24 | Q_DECLARE_METATYPE(QScriptValue*); | |
25 | Q_DECLARE_METATYPE(QScriptValue); | |
26 | ||
27 | class tst_QScriptValue : public QObject { | |
28 | Q_OBJECT | |
29 | ||
30 | public: | |
31 | tst_QScriptValue() {} | |
32 | virtual ~tst_QScriptValue() {} | |
33 | ||
34 | private slots: | |
35 | void toString_data(); | |
36 | void toString(); | |
37 | void copyConstructor_data(); | |
38 | void copyConstructor(); | |
39 | void assignOperator_data(); | |
40 | void assignOperator(); | |
41 | void dataSharing(); | |
42 | void constructors_data(); | |
43 | void constructors(); | |
44 | void call(); | |
45 | ||
46 | // copied from Qt's QtScript. | |
47 | void ctor(); | |
48 | }; | |
49 | ||
50 | void tst_QScriptValue::ctor() | |
51 | { | |
52 | QScriptEngine eng; | |
53 | { | |
54 | QScriptValue v; | |
55 | QCOMPARE(v.isValid(), false); | |
56 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
57 | } | |
58 | { | |
59 | QScriptValue v(&eng, QScriptValue::UndefinedValue); | |
60 | QCOMPARE(v.isValid(), true); | |
61 | QCOMPARE(v.isUndefined(), true); | |
62 | QCOMPARE(v.isObject(), false); | |
63 | QCOMPARE(v.engine(), &eng); | |
64 | } | |
65 | { | |
66 | QScriptValue v(&eng, QScriptValue::NullValue); | |
67 | QCOMPARE(v.isValid(), true); | |
68 | QCOMPARE(v.isNull(), true); | |
69 | QCOMPARE(v.isObject(), false); | |
70 | QCOMPARE(v.engine(), &eng); | |
71 | } | |
72 | { | |
73 | QScriptValue v(&eng, false); | |
74 | QCOMPARE(v.isValid(), true); | |
75 | QCOMPARE(v.isBoolean(), true); | |
76 | QCOMPARE(v.isBool(), true); | |
77 | QCOMPARE(v.isObject(), false); | |
78 | QCOMPARE(v.toBoolean(), false); | |
79 | QCOMPARE(v.engine(), &eng); | |
80 | } | |
81 | { | |
82 | QScriptValue v(&eng, int(1)); | |
83 | QCOMPARE(v.isValid(), true); | |
84 | QCOMPARE(v.isNumber(), true); | |
85 | QCOMPARE(v.isObject(), false); | |
86 | QCOMPARE(v.toNumber(), 1.0); | |
87 | QCOMPARE(v.engine(), &eng); | |
88 | } | |
89 | { | |
90 | QScriptValue v(int(0x43211234)); | |
91 | QVERIFY(v.isNumber()); | |
92 | QCOMPARE(v.toInt32(), 0x43211234); | |
93 | } | |
94 | { | |
95 | QScriptValue v(&eng, uint(1)); | |
96 | QCOMPARE(v.isValid(), true); | |
97 | QCOMPARE(v.isNumber(), true); | |
98 | QCOMPARE(v.isObject(), false); | |
99 | QCOMPARE(v.toNumber(), 1.0); | |
100 | QCOMPARE(v.engine(), &eng); | |
101 | } | |
102 | { | |
103 | QScriptValue v(uint(0x43211234)); | |
104 | QVERIFY(v.isNumber()); | |
105 | QCOMPARE(v.toUInt32(), uint(0x43211234)); | |
106 | } | |
107 | { | |
108 | QScriptValue v(&eng, 1.0); | |
109 | QCOMPARE(v.isValid(), true); | |
110 | QCOMPARE(v.isNumber(), true); | |
111 | QCOMPARE(v.isObject(), false); | |
112 | QCOMPARE(v.toNumber(), 1.0); | |
113 | QCOMPARE(v.engine(), &eng); | |
114 | } | |
115 | { | |
116 | QScriptValue v(12345678910.5); | |
117 | QVERIFY(v.isNumber()); | |
118 | QCOMPARE(v.toNumber(), 12345678910.5); | |
119 | } | |
120 | { | |
121 | QScriptValue v(&eng, "ciao"); | |
122 | QCOMPARE(v.isValid(), true); | |
123 | QCOMPARE(v.isString(), true); | |
124 | QCOMPARE(v.isObject(), false); | |
125 | QCOMPARE(v.toString(), QLatin1String("ciao")); | |
126 | QCOMPARE(v.engine(), &eng); | |
127 | } | |
128 | { | |
129 | QScriptValue v(&eng, QString("ciao")); | |
130 | QCOMPARE(v.isValid(), true); | |
131 | QCOMPARE(v.isString(), true); | |
132 | QCOMPARE(v.isObject(), false); | |
133 | QCOMPARE(v.toString(), QLatin1String("ciao")); | |
134 | QCOMPARE(v.engine(), &eng); | |
135 | } | |
136 | // copy constructor, operator= | |
137 | { | |
138 | QScriptValue v(&eng, 1.0); | |
139 | QScriptValue v2(v); | |
140 | QCOMPARE(v2.strictlyEquals(v), true); | |
141 | QCOMPARE(v2.engine(), &eng); | |
142 | ||
143 | QScriptValue v3(v); | |
144 | QCOMPARE(v3.strictlyEquals(v), true); | |
145 | QCOMPARE(v3.strictlyEquals(v2), true); | |
146 | QCOMPARE(v3.engine(), &eng); | |
147 | ||
148 | QScriptValue v4(&eng, 2.0); | |
149 | QCOMPARE(v4.strictlyEquals(v), false); | |
150 | v3 = v4; | |
151 | QCOMPARE(v3.strictlyEquals(v), false); | |
152 | QCOMPARE(v3.strictlyEquals(v4), true); | |
153 | ||
154 | v2 = QScriptValue(); | |
155 | QCOMPARE(v2.strictlyEquals(v), false); | |
156 | QCOMPARE(v.toNumber(), 1.0); | |
157 | ||
158 | QScriptValue v5(v); | |
159 | QCOMPARE(v5.strictlyEquals(v), true); | |
160 | v = QScriptValue(); | |
161 | QCOMPARE(v5.strictlyEquals(v), false); | |
162 | QCOMPARE(v5.toNumber(), 1.0); | |
163 | } | |
164 | ||
165 | // constructors that take no engine argument | |
166 | { | |
167 | QScriptValue v(QScriptValue::UndefinedValue); | |
168 | QCOMPARE(v.isValid(), true); | |
169 | QCOMPARE(v.isUndefined(), true); | |
170 | QCOMPARE(v.isObject(), false); | |
171 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
172 | } | |
173 | { | |
174 | QScriptValue v(QScriptValue::NullValue); | |
175 | QCOMPARE(v.isValid(), true); | |
176 | QCOMPARE(v.isNull(), true); | |
177 | QCOMPARE(v.isObject(), false); | |
178 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
179 | } | |
180 | { | |
181 | QScriptValue v(false); | |
182 | QCOMPARE(v.isValid(), true); | |
183 | QCOMPARE(v.isBoolean(), true); | |
184 | QCOMPARE(v.isBool(), true); | |
185 | QCOMPARE(v.isObject(), false); | |
186 | QCOMPARE(v.toBoolean(), false); | |
187 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
188 | } | |
189 | { | |
190 | QScriptValue v(int(1)); | |
191 | QCOMPARE(v.isValid(), true); | |
192 | QCOMPARE(v.isNumber(), true); | |
193 | QCOMPARE(v.isObject(), false); | |
194 | QCOMPARE(v.toNumber(), 1.0); | |
195 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
196 | } | |
197 | { | |
198 | QScriptValue v(uint(1)); | |
199 | QCOMPARE(v.isValid(), true); | |
200 | QCOMPARE(v.isNumber(), true); | |
201 | QCOMPARE(v.isObject(), false); | |
202 | QCOMPARE(v.toNumber(), 1.0); | |
203 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
204 | } | |
205 | { | |
206 | QScriptValue v(1.0); | |
207 | QCOMPARE(v.isValid(), true); | |
208 | QCOMPARE(v.isNumber(), true); | |
209 | QCOMPARE(v.isObject(), false); | |
210 | QCOMPARE(v.toNumber(), 1.0); | |
211 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
212 | } | |
213 | { | |
214 | QScriptValue v("ciao"); | |
215 | QCOMPARE(v.isValid(), true); | |
216 | QCOMPARE(v.isString(), true); | |
217 | QCOMPARE(v.isObject(), false); | |
218 | QCOMPARE(v.toString(), QLatin1String("ciao")); | |
219 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
220 | } | |
221 | { | |
222 | QScriptValue v(QString("ciao")); | |
223 | QCOMPARE(v.isValid(), true); | |
224 | QCOMPARE(v.isString(), true); | |
225 | QCOMPARE(v.isObject(), false); | |
226 | QCOMPARE(v.toString(), QLatin1String("ciao")); | |
227 | QCOMPARE(v.engine(), (QScriptEngine *)0); | |
228 | } | |
229 | // copy constructor, operator= | |
230 | { | |
231 | QScriptValue v(1.0); | |
232 | QScriptValue v2(v); | |
233 | QCOMPARE(v2.strictlyEquals(v), true); | |
234 | QCOMPARE(v2.engine(), (QScriptEngine *)0); | |
235 | ||
236 | QScriptValue v3(v); | |
237 | QCOMPARE(v3.strictlyEquals(v), true); | |
238 | QCOMPARE(v3.strictlyEquals(v2), true); | |
239 | QCOMPARE(v3.engine(), (QScriptEngine *)0); | |
240 | ||
241 | QScriptValue v4(2.0); | |
242 | QCOMPARE(v4.strictlyEquals(v), false); | |
243 | v3 = v4; | |
244 | QCOMPARE(v3.strictlyEquals(v), false); | |
245 | QCOMPARE(v3.strictlyEquals(v4), true); | |
246 | ||
247 | v2 = QScriptValue(); | |
248 | QCOMPARE(v2.strictlyEquals(v), false); | |
249 | QCOMPARE(v.toNumber(), 1.0); | |
250 | ||
251 | QScriptValue v5(v); | |
252 | QCOMPARE(v5.strictlyEquals(v), true); | |
253 | v = QScriptValue(); | |
254 | QCOMPARE(v5.strictlyEquals(v), false); | |
255 | QCOMPARE(v5.toNumber(), 1.0); | |
256 | } | |
257 | ||
258 | // 0 engine | |
259 | QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined()); | |
260 | QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull()); | |
261 | QVERIFY(QScriptValue(0, false).isBool()); | |
262 | QVERIFY(QScriptValue(0, int(1)).isNumber()); | |
263 | QVERIFY(QScriptValue(0, uint(1)).isNumber()); | |
264 | QVERIFY(QScriptValue(0, 1.0).isNumber()); | |
265 | QVERIFY(QScriptValue(0, "ciao").isString()); | |
266 | QVERIFY(QScriptValue(0, QString("ciao")).isString()); | |
267 | } | |
268 | ||
269 | void tst_QScriptValue::toString_data() | |
270 | { | |
271 | QTest::addColumn<QString>("code"); | |
272 | QTest::addColumn<QString>("result"); | |
273 | ||
274 | QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello"); | |
275 | QTest::newRow("string utf") << QString::fromUtf8("'ąśćżźółńę'") << QString::fromUtf8("ąśćżźółńę"); | |
276 | QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5"); | |
277 | QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null"); | |
278 | QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false"); | |
279 | QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined"); | |
280 | QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]"); | |
281 | } | |
282 | ||
283 | /* Test conversion to string from different JSC types */ | |
284 | void tst_QScriptValue::toString() | |
285 | { | |
286 | QFETCH(QString, code); | |
287 | QFETCH(QString, result); | |
288 | ||
289 | QScriptEngine engine; | |
290 | QCOMPARE(engine.evaluate(code).toString(), result); | |
291 | } | |
292 | ||
293 | void tst_QScriptValue::copyConstructor_data() | |
294 | { | |
295 | QScriptEngine engine; | |
296 | QScriptValue nnumber(123); | |
297 | QScriptValue nstring("ping"); | |
298 | QScriptValue number(engine.evaluate("1")); | |
299 | QScriptValue string(engine.evaluate("'foo'")); | |
300 | QScriptValue object(engine.evaluate("new Object")); | |
301 | QScriptValue undefined(engine.evaluate("undefined")); | |
302 | QScriptValue null(engine.evaluate("null")); | |
303 | ||
304 | QTest::addColumn<QScriptValue>("value"); | |
305 | QTest::addColumn<QString>("result"); | |
306 | ||
307 | QTest::newRow("native number") << nnumber << QString::number(123); | |
308 | QTest::newRow("native string") << nstring << QString("ping"); | |
309 | QTest::newRow("number") << number << QString::fromAscii("1"); | |
310 | QTest::newRow("string") << string << QString::fromAscii("foo"); | |
311 | QTest::newRow("object") << object << QString::fromAscii("[object Object]"); | |
312 | QTest::newRow("undefined") << undefined << QString::fromAscii("undefined"); | |
313 | QTest::newRow("null") << null << QString::fromAscii("null"); | |
314 | } | |
315 | ||
316 | void tst_QScriptValue::copyConstructor() | |
317 | { | |
318 | QFETCH(QScriptValue, value); | |
319 | QFETCH(QString, result); | |
320 | ||
321 | QVERIFY(value.isValid()); | |
322 | QScriptValue tmp(value); | |
323 | QVERIFY(tmp.isValid()); | |
324 | QCOMPARE(tmp.toString(), result); | |
325 | } | |
326 | ||
327 | void tst_QScriptValue::assignOperator_data() | |
328 | { | |
329 | copyConstructor_data(); | |
330 | } | |
331 | ||
332 | void tst_QScriptValue::assignOperator() | |
333 | { | |
334 | QFETCH(QScriptValue, value); | |
335 | QFETCH(QString, result); | |
336 | ||
337 | QScriptValue tmp; | |
338 | tmp = value; | |
339 | QVERIFY(tmp.isValid()); | |
340 | QCOMPARE(tmp.toString(), result); | |
341 | } | |
342 | ||
343 | /* Test internal data sharing between a diffrenet QScriptValue. */ | |
344 | void tst_QScriptValue::dataSharing() | |
345 | { | |
346 | QScriptEngine engine; | |
347 | QScriptValue v1; | |
348 | QScriptValue v2(v1); | |
349 | ||
350 | v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid. | |
351 | QVERIFY(v1.isValid()); | |
352 | QVERIFY(!v2.isValid()); | |
353 | ||
354 | v2 = v1; // v1 == 1; v2 == 1. | |
355 | QVERIFY(v1.isValid()); | |
356 | QVERIFY(v2.isValid()); | |
357 | ||
358 | v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1. | |
359 | QVERIFY(v1.isValid()); | |
360 | QVERIFY(v2.isValid()); | |
361 | QVERIFY(v2.toString() != v1.toString()); | |
362 | ||
363 | // TODO add object manipulation (v1 and v2 point to the same object). | |
364 | } | |
365 | ||
366 | void tst_QScriptValue::constructors_data() | |
367 | { | |
368 | QScriptEngine engine; | |
369 | ||
370 | QTest::addColumn<QScriptValue>("value"); | |
371 | QTest::addColumn<QString>("string"); | |
372 | QTest::addColumn<bool>("valid"); | |
373 | QTest::addColumn<bool>("object"); | |
374 | ||
375 | QTest::newRow("invalid") << QScriptValue() << QString() << false << false; | |
376 | QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false; | |
377 | QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false; | |
378 | QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false; | |
379 | QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false; | |
380 | QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true; | |
381 | QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false; | |
382 | QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false; | |
383 | } | |
384 | ||
385 | void tst_QScriptValue::constructors() | |
386 | { | |
387 | QFETCH(QScriptValue, value); | |
388 | QFETCH(QString, string); | |
389 | QFETCH(bool, valid); | |
390 | QFETCH(bool, object); | |
391 | ||
392 | QCOMPARE(value.isValid(), valid); | |
393 | QCOMPARE(value.toString(), string); | |
394 | QCOMPARE(value.isObject(), object); | |
395 | } | |
396 | ||
397 | void tst_QScriptValue::call() | |
398 | { | |
399 | QScriptEngine engine; | |
400 | QScriptValue ping = engine.evaluate("( function() {return 'ping';} )"); | |
401 | QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )"); | |
402 | QScriptValue one(1); | |
403 | QScriptValue five(5); | |
404 | QScriptValue result; | |
405 | ||
406 | QVERIFY(one.isValid()); | |
407 | QVERIFY(five.isValid()); | |
408 | ||
409 | QVERIFY(ping.isValid()); | |
410 | QVERIFY(ping.isFunction()); | |
411 | result = ping.call(); | |
412 | QVERIFY(result.isValid()); | |
413 | QCOMPARE(result.toString(), QString::fromUtf8("ping")); | |
414 | ||
415 | QVERIFY(incr.isValid()); | |
416 | QVERIFY(incr.isFunction()); | |
417 | result = incr.call(QScriptValue(), QScriptValueList() << one); | |
418 | QVERIFY(result.isValid()); | |
419 | QCOMPARE(result.toString(), QString("2")); | |
420 | ||
421 | QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6")); | |
422 | ||
423 | QVERIFY(incr.call().isValid()); // Exception. | |
424 | } | |
425 | ||
426 | QTEST_MAIN(tst_QScriptValue) | |
427 | #include "tst_qscriptvalue.moc" |