Fixes a crash in QDoubleSpinBox
[qt-netbsd.git] / tests / auto / qscriptvalueiterator / tst_qscriptvalueiterator.cpp
blobdc88268fcd10b631207090547c9c5bf10281a40a
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial Usage
11 ** Licensees holding valid Qt Commercial licenses may use this file in
12 ** accordance with the Qt Commercial License Agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and Nokia.
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
43 #include <QtTest/QtTest>
45 #include <QtScript/qscriptengine.h>
46 #include <QtScript/qscriptvalueiterator.h>
48 //TESTED_CLASS=
49 //TESTED_FILES=
51 class tst_QScriptValueIterator : public QObject
53 Q_OBJECT
55 public:
56 tst_QScriptValueIterator();
57 virtual ~tst_QScriptValueIterator();
59 private slots:
60 void iterateForward_data();
61 void iterateForward();
62 void iterateBackward_data();
63 void iterateBackward();
64 void iterateArray();
65 void iterateBackAndForth();
66 void setValue();
67 void remove();
68 void iterateString();
69 void iterateGetterSetter();
70 void iterateArgumentsObject();
71 void assignObjectToIterator();
72 void undefinedBehavior();
75 tst_QScriptValueIterator::tst_QScriptValueIterator()
79 tst_QScriptValueIterator::~tst_QScriptValueIterator()
83 void tst_QScriptValueIterator::iterateForward_data()
85 QTest::addColumn<QStringList>("propertyNames");
86 QTest::addColumn<QStringList>("propertyValues");
88 QTest::newRow("no properties")
89 << QStringList() << QStringList();
90 QTest::newRow("foo=bar")
91 << (QStringList() << "foo")
92 << (QStringList() << "bar");
93 QTest::newRow("foo=bar, baz=123")
94 << (QStringList() << "foo" << "baz")
95 << (QStringList() << "bar" << "123");
96 QTest::newRow("foo=bar, baz=123, rab=oof")
97 << (QStringList() << "foo" << "baz" << "rab")
98 << (QStringList() << "bar" << "123" << "oof");
101 void tst_QScriptValueIterator::iterateForward()
103 QFETCH(QStringList, propertyNames);
104 QFETCH(QStringList, propertyValues);
105 QMap<QString, QString> pmap;
106 Q_ASSERT(propertyNames.size() == propertyValues.size());
108 QScriptEngine engine;
109 QScriptValue object = engine.newObject();
110 for (int i = 0; i < propertyNames.size(); ++i) {
111 QString name = propertyNames.at(i);
112 QString value = propertyValues.at(i);
113 pmap.insert(name, value);
114 object.setProperty(name, QScriptValue(&engine, value));
116 QScriptValue otherObject = engine.newObject();
117 otherObject.setProperty("foo", QScriptValue(&engine, 123456));
118 otherObject.setProperty("protoProperty", QScriptValue(&engine, 654321));
119 object.setPrototype(otherObject); // should not affect iterator
121 QStringList lst;
122 QScriptValueIterator it(object);
123 while (!pmap.isEmpty()) {
124 QCOMPARE(it.hasNext(), true);
125 QCOMPARE(it.hasNext(), true);
126 it.next();
127 QString name = it.name();
128 QCOMPARE(pmap.contains(name), true);
129 QCOMPARE(it.name(), name);
130 QCOMPARE(it.flags(), object.propertyFlags(name));
131 QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true);
132 QCOMPARE(it.scriptName(), engine.toStringHandle(name));
133 pmap.remove(name);
134 lst.append(name);
137 QCOMPARE(it.hasNext(), false);
138 QCOMPARE(it.hasNext(), false);
140 it.toFront();
141 for (int i = 0; i < lst.count(); ++i) {
142 QCOMPARE(it.hasNext(), true);
143 it.next();
144 QCOMPARE(it.name(), lst.at(i));
147 for (int i = 0; i < lst.count(); ++i) {
148 QCOMPARE(it.hasPrevious(), true);
149 it.previous();
150 QCOMPARE(it.name(), lst.at(lst.count()-1-i));
152 QCOMPARE(it.hasPrevious(), false);
155 void tst_QScriptValueIterator::iterateBackward_data()
157 iterateForward_data();
160 void tst_QScriptValueIterator::iterateBackward()
162 QFETCH(QStringList, propertyNames);
163 QFETCH(QStringList, propertyValues);
164 QMap<QString, QString> pmap;
165 Q_ASSERT(propertyNames.size() == propertyValues.size());
167 QScriptEngine engine;
168 QScriptValue object = engine.newObject();
169 for (int i = 0; i < propertyNames.size(); ++i) {
170 QString name = propertyNames.at(i);
171 QString value = propertyValues.at(i);
172 pmap.insert(name, value);
173 object.setProperty(name, QScriptValue(&engine, value));
176 QStringList lst;
177 QScriptValueIterator it(object);
178 it.toBack();
179 while (!pmap.isEmpty()) {
180 QCOMPARE(it.hasPrevious(), true);
181 QCOMPARE(it.hasPrevious(), true);
182 it.previous();
183 QString name = it.name();
184 QCOMPARE(pmap.contains(name), true);
185 QCOMPARE(it.name(), name);
186 QCOMPARE(it.flags(), object.propertyFlags(name));
187 QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true);
188 pmap.remove(name);
189 lst.append(name);
192 QCOMPARE(it.hasPrevious(), false);
193 QCOMPARE(it.hasPrevious(), false);
195 it.toBack();
196 for (int i = 0; i < lst.count(); ++i) {
197 QCOMPARE(it.hasPrevious(), true);
198 it.previous();
199 QCOMPARE(it.name(), lst.at(i));
202 for (int i = 0; i < lst.count(); ++i) {
203 QCOMPARE(it.hasNext(), true);
204 it.next();
205 QCOMPARE(it.name(), lst.at(lst.count()-1-i));
207 QCOMPARE(it.hasNext(), false);
210 void tst_QScriptValueIterator::iterateArray()
212 QScriptEngine engine;
213 QScriptValue array = engine.newArray();
214 array.setProperty("0", QScriptValue(&engine, 123));
215 array.setProperty("1", QScriptValue(&engine, 456));
216 array.setProperty("2", QScriptValue(&engine, 789));
217 int length = array.property("length").toInt32();
218 QCOMPARE(length, 3);
219 QScriptValueIterator it(array);
220 for (int i = 0; i < length; ++i) {
221 QCOMPARE(it.hasNext(), true);
222 QString indexStr = QScriptValue(&engine, i).toString();
223 it.next();
224 QCOMPARE(it.name(), indexStr);
225 QCOMPARE(it.flags(), array.propertyFlags(indexStr));
226 QCOMPARE(it.value().strictlyEquals(array.property(indexStr)), true);
228 QCOMPARE(it.hasNext(), false);
230 for (int i = length - 1; i >= 0; --i) {
231 it.previous();
232 QString indexStr = QScriptValue(&engine, i).toString();
233 QCOMPARE(it.name(), indexStr);
234 QCOMPARE(it.value().strictlyEquals(array.property(indexStr)), true);
235 QCOMPARE(it.hasPrevious(), i > 0);
237 QCOMPARE(it.hasPrevious(), false);
239 // hasNext() and hasPrevious() cache their result; verify that the result is in sync
240 QVERIFY(it.hasNext());
241 it.next();
242 QCOMPARE(it.name(), QString::fromLatin1("0"));
243 QVERIFY(it.hasNext());
244 it.previous();
245 QCOMPARE(it.name(), QString::fromLatin1("0"));
246 QVERIFY(!it.hasPrevious());
247 it.next();
248 QCOMPARE(it.name(), QString::fromLatin1("0"));
249 QVERIFY(it.hasPrevious());
250 it.next();
251 QCOMPARE(it.name(), QString::fromLatin1("1"));
254 void tst_QScriptValueIterator::iterateBackAndForth()
256 QScriptEngine engine;
258 QScriptValue object = engine.newObject();
259 object.setProperty("foo", QScriptValue(&engine, "bar"));
260 object.setProperty("rab", QScriptValue(&engine, "oof"),
261 QScriptValue::SkipInEnumeration); // should not affect iterator
262 QScriptValueIterator it(object);
263 it.next();
264 QCOMPARE(it.name(), QLatin1String("foo"));
265 it.previous();
266 QCOMPARE(it.name(), QLatin1String("foo"));
267 it.next();
268 QCOMPARE(it.name(), QLatin1String("foo"));
269 it.previous();
270 QCOMPARE(it.name(), QLatin1String("foo"));
271 it.next();
272 QCOMPARE(it.name(), QLatin1String("foo"));
273 it.next();
274 QCOMPARE(it.name(), QLatin1String("rab"));
275 it.previous();
276 QCOMPARE(it.name(), QLatin1String("rab"));
277 it.next();
278 QCOMPARE(it.name(), QLatin1String("rab"));
279 it.previous();
280 QCOMPARE(it.name(), QLatin1String("rab"));
283 // hasNext() and hasPrevious() cache their result; verify that the result is in sync
284 QScriptValue object = engine.newObject();
285 object.setProperty("foo", QScriptValue(&engine, "bar"));
286 object.setProperty("rab", QScriptValue(&engine, "oof"));
287 QScriptValueIterator it(object);
288 QVERIFY(it.hasNext());
289 it.next();
290 QCOMPARE(it.name(), QString::fromLatin1("foo"));
291 QVERIFY(it.hasNext());
292 it.previous();
293 QCOMPARE(it.name(), QString::fromLatin1("foo"));
294 QVERIFY(!it.hasPrevious());
295 it.next();
296 QCOMPARE(it.name(), QString::fromLatin1("foo"));
297 QVERIFY(it.hasPrevious());
298 it.next();
299 QCOMPARE(it.name(), QString::fromLatin1("rab"));
303 void tst_QScriptValueIterator::setValue()
305 QScriptEngine engine;
306 QScriptValue object = engine.newObject();
307 object.setProperty("foo", QScriptValue(&engine, "bar"));
308 QScriptValueIterator it(object);
309 it.next();
310 QCOMPARE(it.name(), QLatin1String("foo"));
311 it.setValue(QScriptValue(&engine, "baz"));
312 QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("baz"))), true);
313 QCOMPARE(object.property("foo").toString(), QLatin1String("baz"));
314 it.setValue(QScriptValue(&engine, "zab"));
315 QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("zab"))), true);
316 QCOMPARE(object.property("foo").toString(), QLatin1String("zab"));
319 void tst_QScriptValueIterator::remove()
321 QScriptEngine engine;
322 QScriptValue object = engine.newObject();
323 object.setProperty("foo", QScriptValue(&engine, "bar"),
324 QScriptValue::SkipInEnumeration); // should not affect iterator
325 object.setProperty("rab", QScriptValue(&engine, "oof"));
326 QScriptValueIterator it(object);
327 it.next();
328 QCOMPARE(it.name(), QLatin1String("foo"));
329 it.remove();
330 QCOMPARE(it.hasPrevious(), false);
331 QCOMPARE(object.property("foo").isValid(), false);
332 QCOMPARE(object.property("rab").toString(), QLatin1String("oof"));
333 it.next();
334 QCOMPARE(it.name(), QLatin1String("rab"));
335 QCOMPARE(it.value().toString(), QLatin1String("oof"));
336 QCOMPARE(it.hasNext(), false);
337 it.remove();
338 QCOMPARE(object.property("rab").isValid(), false);
339 QCOMPARE(it.hasPrevious(), false);
340 QCOMPARE(it.hasNext(), false);
343 void tst_QScriptValueIterator::iterateString()
345 QScriptEngine engine;
346 QScriptValue str = QScriptValue(&engine, QString::fromLatin1("ciao"));
347 QVERIFY(str.isString());
348 QScriptValue obj = str.toObject();
349 int length = obj.property("length").toInt32();
350 QCOMPARE(length, 4);
351 QScriptValueIterator it(obj);
352 for (int i = 0; i < length; ++i) {
353 QCOMPARE(it.hasNext(), true);
354 QString indexStr = QScriptValue(&engine, i).toString();
355 it.next();
356 QCOMPARE(it.name(), indexStr);
357 QCOMPARE(it.flags(), obj.propertyFlags(indexStr));
358 QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true);
360 QCOMPARE(it.hasNext(), false);
362 for (int i = length - 1; i >= 0; --i) {
363 it.previous();
364 QString indexStr = QScriptValue(&engine, i).toString();
365 QCOMPARE(it.name(), indexStr);
366 QCOMPARE(it.flags(), obj.propertyFlags(indexStr));
367 QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true);
368 QCOMPARE(it.hasPrevious(), i > 0);
370 QCOMPARE(it.hasPrevious(), false);
373 static QScriptValue myGetterSetter(QScriptContext *ctx, QScriptEngine *)
375 if (ctx->argumentCount() == 1)
376 ctx->thisObject().setProperty("bar", ctx->argument(0));
377 return ctx->thisObject().property("bar");
380 static QScriptValue myGetter(QScriptContext *ctx, QScriptEngine *)
382 return ctx->thisObject().property("bar");
385 static QScriptValue mySetter(QScriptContext *ctx, QScriptEngine *)
387 ctx->thisObject().setProperty("bar", ctx->argument(0));
388 return ctx->argument(0);
391 void tst_QScriptValueIterator::iterateGetterSetter()
393 // unified getter/setter function
395 QScriptEngine eng;
396 QScriptValue obj = eng.newObject();
397 obj.setProperty("foo", eng.newFunction(myGetterSetter),
398 QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
399 QScriptValue val(&eng, 123);
400 obj.setProperty("foo", val);
401 QVERIFY(obj.property("bar").strictlyEquals(val));
402 QVERIFY(obj.property("foo").strictlyEquals(val));
404 QScriptValueIterator it(obj);
405 QVERIFY(it.hasNext());
406 it.next();
407 QCOMPARE(it.name(), QString::fromLatin1("foo"));
408 QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::PropertyGetter | QScriptValue::PropertySetter));
409 QVERIFY(it.value().strictlyEquals(val));
410 QScriptValue val2(&eng, 456);
411 it.setValue(val2);
412 QVERIFY(obj.property("bar").strictlyEquals(val2));
413 QVERIFY(obj.property("foo").strictlyEquals(val2));
415 QVERIFY(it.hasNext());
416 it.next();
417 QCOMPARE(it.name(), QString::fromLatin1("bar"));
418 QVERIFY(!it.hasNext());
420 QVERIFY(it.hasPrevious());
421 it.previous();
422 QCOMPARE(it.name(), QString::fromLatin1("bar"));
423 QVERIFY(it.hasPrevious());
424 it.previous();
425 QCOMPARE(it.name(), QString::fromLatin1("foo"));
426 QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::PropertyGetter | QScriptValue::PropertySetter));
427 QVERIFY(it.value().strictlyEquals(val2));
428 it.setValue(val);
429 QVERIFY(obj.property("bar").strictlyEquals(val));
430 QVERIFY(obj.property("foo").strictlyEquals(val));
432 // separate getter/setter function
433 for (int x = 0; x < 2; ++x) {
434 QScriptEngine eng;
435 QScriptValue obj = eng.newObject();
436 if (x == 0) {
437 obj.setProperty("foo", eng.newFunction(myGetter), QScriptValue::PropertyGetter);
438 obj.setProperty("foo", eng.newFunction(mySetter), QScriptValue::PropertySetter);
439 } else {
440 obj.setProperty("foo", eng.newFunction(mySetter), QScriptValue::PropertySetter);
441 obj.setProperty("foo", eng.newFunction(myGetter), QScriptValue::PropertyGetter);
443 QScriptValue val(&eng, 123);
444 obj.setProperty("foo", val);
445 QVERIFY(obj.property("bar").strictlyEquals(val));
446 QVERIFY(obj.property("foo").strictlyEquals(val));
448 QScriptValueIterator it(obj);
449 QVERIFY(it.hasNext());
450 it.next();
451 QCOMPARE(it.name(), QString::fromLatin1("foo"));
452 QVERIFY(it.value().strictlyEquals(val));
453 QScriptValue val2(&eng, 456);
454 it.setValue(val2);
455 QVERIFY(obj.property("bar").strictlyEquals(val2));
456 QVERIFY(obj.property("foo").strictlyEquals(val2));
458 QVERIFY(it.hasNext());
459 it.next();
460 QCOMPARE(it.name(), QString::fromLatin1("bar"));
461 QVERIFY(!it.hasNext());
463 QVERIFY(it.hasPrevious());
464 it.previous();
465 QCOMPARE(it.name(), QString::fromLatin1("bar"));
466 QVERIFY(it.hasPrevious());
467 it.previous();
468 QCOMPARE(it.name(), QString::fromLatin1("foo"));
469 QVERIFY(it.value().strictlyEquals(val2));
470 it.setValue(val);
471 QVERIFY(obj.property("bar").strictlyEquals(val));
472 QVERIFY(obj.property("foo").strictlyEquals(val));
476 static QScriptValue getArgumentsObject(QScriptContext *ctx, QScriptEngine *)
478 return ctx->argumentsObject();
481 void tst_QScriptValueIterator::iterateArgumentsObject()
483 QScriptEngine eng;
484 QScriptValue fun = eng.newFunction(getArgumentsObject);
485 QScriptValue ret = fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123) << QScriptValue(&eng, 456));
486 QCOMPARE(ret.property("length").toInt32(), 2);
488 QScriptValueIterator it(ret);
489 QVERIFY(it.hasNext());
490 it.next();
491 QCOMPARE(it.name(), QString::fromLatin1("callee"));
492 QVERIFY(it.value().isFunction());
493 QVERIFY(it.value().strictlyEquals(fun));
494 QVERIFY(it.hasNext());
496 it.next();
497 QCOMPARE(it.name(), QString::fromLatin1("length"));
498 QVERIFY(it.value().isNumber());
499 QCOMPARE(it.value().toInt32(), 2);
500 QVERIFY(it.hasNext());
502 it.next();
503 QCOMPARE(it.name(), QString::fromLatin1("0"));
504 QVERIFY(it.value().isNumber());
505 QCOMPARE(it.value().toInt32(), 123);
506 QVERIFY(it.hasNext());
508 it.next();
509 QCOMPARE(it.name(), QString::fromLatin1("1"));
510 QVERIFY(it.value().isNumber());
511 QCOMPARE(it.value().toInt32(), 456);
512 QVERIFY(!it.hasNext());
514 QVERIFY(it.hasPrevious());
515 it.previous();
516 QCOMPARE(it.name(), QString::fromLatin1("1"));
517 QVERIFY(it.value().isNumber());
518 QCOMPARE(it.value().toInt32(), 456);
519 QVERIFY(it.hasPrevious());
521 it.previous();
522 QCOMPARE(it.name(), QString::fromLatin1("0"));
523 QVERIFY(it.value().isNumber());
524 QCOMPARE(it.value().toInt32(), 123);
525 QVERIFY(it.hasPrevious());
527 it.previous();
528 QCOMPARE(it.name(), QString::fromLatin1("length"));
529 QVERIFY(it.value().isNumber());
530 QCOMPARE(it.value().toInt32(), 2);
531 QVERIFY(it.hasPrevious());
533 it.previous();
534 QCOMPARE(it.name(), QString::fromLatin1("callee"));
535 QVERIFY(it.value().isFunction());
536 QVERIFY(it.value().strictlyEquals(fun));
537 QVERIFY(!it.hasPrevious());
540 void tst_QScriptValueIterator::undefinedBehavior()
542 QScriptEngine eng;
543 QScriptValue obj = eng.newObject();
544 obj.setProperty("foo", QScriptValue(&eng, 123));
546 QScriptValueIterator it(obj);
547 QVERIFY(it.hasNext());
549 // delete the property
550 obj.setProperty("foo", QScriptValue());
552 it.next();
553 QCOMPARE(it.name(), QString::fromLatin1("foo"));
554 QVERIFY(!it.value().isValid());
556 QVERIFY(!it.hasNext());
557 // add a property
558 obj.setProperty("bar", QScriptValue(&eng, 123));
559 QVERIFY(it.hasNext());
561 it.next();
562 QCOMPARE(it.name(), QString::fromLatin1("bar"));
563 QVERIFY(it.value().isNumber());
566 void tst_QScriptValueIterator::assignObjectToIterator()
568 QScriptEngine eng;
569 QScriptValue obj1 = eng.newObject();
570 obj1.setProperty("foo", 123);
571 QScriptValue obj2 = eng.newObject();
572 obj2.setProperty("bar", 456);
574 QScriptValueIterator it(obj1);
575 QVERIFY(it.hasNext());
576 it.next();
577 it = obj2;
578 QVERIFY(it.hasNext());
579 it.next();
580 QCOMPARE(it.name(), QString::fromLatin1("bar"));
582 it = obj1;
583 QVERIFY(it.hasNext());
584 it.next();
585 QCOMPARE(it.name(), QString::fromLatin1("foo"));
587 it = obj2;
588 QVERIFY(it.hasNext());
589 it.next();
590 QCOMPARE(it.name(), QString::fromLatin1("bar"));
592 it = obj2;
593 QVERIFY(it.hasNext());
594 it.next();
595 QCOMPARE(it.name(), QString::fromLatin1("bar"));
598 QTEST_MAIN(tst_QScriptValueIterator)
599 #include "tst_qscriptvalueiterator.moc"