]> git.saurik.com Git - apple/javascriptcore.git/blame_incremental - qt/tests/qscriptvalue/tst_qscriptvalue.cpp
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / qt / tests / qscriptvalue / tst_qscriptvalue.cpp
... / ...
CommitLineData
1/*
2 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "tst_qscriptvalue.h"
21#include <QtCore/qnumeric.h>
22
23tst_QScriptValue::tst_QScriptValue()
24 : m_engine(0)
25{
26}
27
28tst_QScriptValue::~tst_QScriptValue()
29{
30 delete m_engine;
31}
32
33void tst_QScriptValue::ctor()
34{
35 QScriptEngine eng;
36 {
37 QScriptValue v;
38 QCOMPARE(v.isValid(), false);
39 QCOMPARE(v.engine(), (QScriptEngine*)0);
40 }
41 {
42 QScriptValue v(&eng, QScriptValue::UndefinedValue);
43 QCOMPARE(v.isValid(), true);
44 QCOMPARE(v.isUndefined(), true);
45 QCOMPARE(v.isObject(), false);
46 QCOMPARE(v.engine(), &eng);
47 }
48 {
49 QScriptValue v(&eng, QScriptValue::NullValue);
50 QCOMPARE(v.isValid(), true);
51 QCOMPARE(v.isNull(), true);
52 QCOMPARE(v.isObject(), false);
53 QCOMPARE(v.engine(), &eng);
54 }
55 {
56 QScriptValue v(&eng, false);
57 QCOMPARE(v.isValid(), true);
58 QCOMPARE(v.isBoolean(), true);
59 QCOMPARE(v.isBool(), true);
60 QCOMPARE(v.isObject(), false);
61 QCOMPARE(v.toBoolean(), false);
62 QCOMPARE(v.engine(), &eng);
63 }
64 {
65 QScriptValue v(&eng, int(1));
66 QCOMPARE(v.isValid(), true);
67 QCOMPARE(v.isNumber(), true);
68 QCOMPARE(v.isObject(), false);
69 QCOMPARE(v.toNumber(), 1.0);
70 QCOMPARE(v.engine(), &eng);
71 }
72 {
73 QScriptValue v(int(0x43211234));
74 QVERIFY(v.isNumber());
75 QCOMPARE(v.toInt32(), 0x43211234);
76 }
77 {
78 QScriptValue v(&eng, uint(1));
79 QCOMPARE(v.isValid(), true);
80 QCOMPARE(v.isNumber(), true);
81 QCOMPARE(v.isObject(), false);
82 QCOMPARE(v.toNumber(), 1.0);
83 QCOMPARE(v.engine(), &eng);
84 }
85 {
86 QScriptValue v(uint(0x43211234));
87 QVERIFY(v.isNumber());
88 QCOMPARE(v.toUInt32(), uint(0x43211234));
89 }
90 {
91 QScriptValue v(&eng, 1.0);
92 QCOMPARE(v.isValid(), true);
93 QCOMPARE(v.isNumber(), true);
94 QCOMPARE(v.isObject(), false);
95 QCOMPARE(v.toNumber(), 1.0);
96 QCOMPARE(v.engine(), &eng);
97 }
98 {
99 QScriptValue v(12345678910.5);
100 QVERIFY(v.isNumber());
101 QCOMPARE(v.toNumber(), 12345678910.5);
102 }
103 {
104 QScriptValue v(&eng, "ciao");
105 QCOMPARE(v.isValid(), true);
106 QCOMPARE(v.isString(), true);
107 QCOMPARE(v.isObject(), false);
108 QCOMPARE(v.toString(), QLatin1String("ciao"));
109 QCOMPARE(v.engine(), &eng);
110 }
111 {
112 QScriptValue v(&eng, QString("ciao"));
113 QCOMPARE(v.isValid(), true);
114 QCOMPARE(v.isString(), true);
115 QCOMPARE(v.isObject(), false);
116 QCOMPARE(v.toString(), QLatin1String("ciao"));
117 QCOMPARE(v.engine(), &eng);
118 }
119 // copy constructor, operator=
120 {
121 QScriptValue v(&eng, 1.0);
122 QScriptValue v2(v);
123 QCOMPARE(v2.strictlyEquals(v), true);
124 QCOMPARE(v2.engine(), &eng);
125
126 QScriptValue v3(v);
127 QCOMPARE(v3.strictlyEquals(v), true);
128 QCOMPARE(v3.strictlyEquals(v2), true);
129 QCOMPARE(v3.engine(), &eng);
130
131 QScriptValue v4(&eng, 2.0);
132 QCOMPARE(v4.strictlyEquals(v), false);
133 v3 = v4;
134 QCOMPARE(v3.strictlyEquals(v), false);
135 QCOMPARE(v3.strictlyEquals(v4), true);
136
137 v2 = QScriptValue();
138 QCOMPARE(v2.strictlyEquals(v), false);
139 QCOMPARE(v.toNumber(), 1.0);
140
141 QScriptValue v5(v);
142 QCOMPARE(v5.strictlyEquals(v), true);
143 v = QScriptValue();
144 QCOMPARE(v5.strictlyEquals(v), false);
145 QCOMPARE(v5.toNumber(), 1.0);
146 }
147
148 // constructors that take no engine argument
149 {
150 QScriptValue v(QScriptValue::UndefinedValue);
151 QCOMPARE(v.isValid(), true);
152 QCOMPARE(v.isUndefined(), true);
153 QCOMPARE(v.isObject(), false);
154 QCOMPARE(v.engine(), (QScriptEngine*)0);
155 }
156 {
157 QScriptValue v(QScriptValue::NullValue);
158 QCOMPARE(v.isValid(), true);
159 QCOMPARE(v.isNull(), true);
160 QCOMPARE(v.isObject(), false);
161 QCOMPARE(v.engine(), (QScriptEngine*)0);
162 }
163 {
164 QScriptValue v(false);
165 QCOMPARE(v.isValid(), true);
166 QCOMPARE(v.isBoolean(), true);
167 QCOMPARE(v.isBool(), true);
168 QCOMPARE(v.isObject(), false);
169 QCOMPARE(v.toBoolean(), false);
170 QCOMPARE(v.engine(), (QScriptEngine*)0);
171 }
172 {
173 QScriptValue v(int(1));
174 QCOMPARE(v.isValid(), true);
175 QCOMPARE(v.isNumber(), true);
176 QCOMPARE(v.isObject(), false);
177 QCOMPARE(v.toNumber(), 1.0);
178 QCOMPARE(v.engine(), (QScriptEngine*)0);
179 }
180 {
181 QScriptValue v(uint(1));
182 QCOMPARE(v.isValid(), true);
183 QCOMPARE(v.isNumber(), true);
184 QCOMPARE(v.isObject(), false);
185 QCOMPARE(v.toNumber(), 1.0);
186 QCOMPARE(v.engine(), (QScriptEngine*)0);
187 }
188 {
189 QScriptValue v(1.0);
190 QCOMPARE(v.isValid(), true);
191 QCOMPARE(v.isNumber(), true);
192 QCOMPARE(v.isObject(), false);
193 QCOMPARE(v.toNumber(), 1.0);
194 QCOMPARE(v.engine(), (QScriptEngine*)0);
195 }
196 {
197 QScriptValue v("ciao");
198 QCOMPARE(v.isValid(), true);
199 QCOMPARE(v.isString(), true);
200 QCOMPARE(v.isObject(), false);
201 QCOMPARE(v.toString(), QLatin1String("ciao"));
202 QCOMPARE(v.engine(), (QScriptEngine*)0);
203 }
204 {
205 QScriptValue v(QString("ciao"));
206 QCOMPARE(v.isValid(), true);
207 QCOMPARE(v.isString(), true);
208 QCOMPARE(v.isObject(), false);
209 QCOMPARE(v.toString(), QLatin1String("ciao"));
210 QCOMPARE(v.engine(), (QScriptEngine*)0);
211 }
212 // copy constructor, operator=
213 {
214 QScriptValue v(1.0);
215 QScriptValue v2(v);
216 QCOMPARE(v2.strictlyEquals(v), true);
217 QCOMPARE(v2.engine(), (QScriptEngine*)0);
218
219 QScriptValue v3(v);
220 QCOMPARE(v3.strictlyEquals(v), true);
221 QCOMPARE(v3.strictlyEquals(v2), true);
222 QCOMPARE(v3.engine(), (QScriptEngine*)0);
223
224 QScriptValue v4(2.0);
225 QCOMPARE(v4.strictlyEquals(v), false);
226 v3 = v4;
227 QCOMPARE(v3.strictlyEquals(v), false);
228 QCOMPARE(v3.strictlyEquals(v4), true);
229
230 v2 = QScriptValue();
231 QCOMPARE(v2.strictlyEquals(v), false);
232 QCOMPARE(v.toNumber(), 1.0);
233
234 QScriptValue v5(v);
235 QCOMPARE(v5.strictlyEquals(v), true);
236 v = QScriptValue();
237 QCOMPARE(v5.strictlyEquals(v), false);
238 QCOMPARE(v5.toNumber(), 1.0);
239 }
240
241 // 0 engine
242 QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
243 QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
244 QVERIFY(QScriptValue(0, false).isBool());
245 QVERIFY(QScriptValue(0, int(1)).isNumber());
246 QVERIFY(QScriptValue(0, uint(1)).isNumber());
247 QVERIFY(QScriptValue(0, 1.0).isNumber());
248 QVERIFY(QScriptValue(0, "ciao").isString());
249 QVERIFY(QScriptValue(0, QString("ciao")).isString());
250}
251
252void tst_QScriptValue::getPropertySimple_data()
253{
254 QTest::addColumn<QString>("code");
255 QTest::addColumn<QString>("propertyName");
256 QTest::addColumn<QString>("desc");
257 QTest::addColumn<bool>("isArrayIndex");
258
259 QTest::newRow("new Array()")
260 << QString::fromAscii("new Array()")
261 << QString::fromAscii("length")
262 << QString::fromAscii("0")
263 << false;
264 QTest::newRow("new Object().length")
265 << QString::fromAscii("new Object()")
266 << QString::fromAscii("length")
267 << QString::fromAscii("") // Undefined is an invalid property.
268 << false;
269 QTest::newRow("new Object().toString")
270 << QString::fromAscii("new Object()")
271 << QString::fromAscii("toString")
272 << QString::fromAscii("function toString() {\n [native code]\n}")
273 << false;
274 QTest::newRow("[1,2,3,4]")
275 << QString::fromAscii("[1,2,3,'s',4]")
276 << QString::fromAscii("2")
277 << QString::fromAscii("3")
278 << true;
279 QTest::newRow("[1,3,'a','b']")
280 << QString::fromAscii("[1,3,'a','b']")
281 << QString::fromAscii("3")
282 << QString::fromAscii("b")
283 << true;
284 QTest::newRow("[4,5]")
285 << QString::fromAscii("[4,5]")
286 << QString::fromAscii("123")
287 << QString::fromAscii("") // Undefined is an invalid property.
288 << true;
289 QTest::newRow("[1,3,4]")
290 << QString::fromAscii("[1,3,4]")
291 << QString::fromAscii("abc")
292 << QString::fromAscii("") // Undefined is an invalid property.
293 << true;
294}
295
296void tst_QScriptValue::getPropertySimple()
297{
298 QFETCH(QString, code);
299 QFETCH(QString, propertyName);
300 QFETCH(QString, desc);
301
302 QScriptEngine engine;
303 QScriptValue object = engine.evaluate(code);
304 QVERIFY(object.isValid());
305 {
306 QScriptValue property = object.property(propertyName);
307 QCOMPARE(property.toString(), desc);
308 }
309 {
310 QScriptString name = engine.toStringHandle(propertyName);
311 QScriptValue property = object.property(name);
312 QCOMPARE(property.toString(), desc);
313 }
314 {
315 bool ok;
316 quint32 idx = engine.toStringHandle(propertyName).toArrayIndex(&ok);
317 if (ok) {
318 QScriptValue property = object.property(idx);
319 QCOMPARE(property.toString(), desc);
320 }
321 }
322}
323
324void tst_QScriptValue::setPropertySimple()
325{
326 QScriptEngine engine;
327 {
328 QScriptValue invalid;
329 QScriptValue property(1234);
330
331 invalid.setProperty("aaa", property);
332 invalid.setProperty(13, property);
333 invalid.setProperty(engine.toStringHandle("aaa"), property);
334
335 QVERIFY(!invalid.property("aaa").isValid());
336 QVERIFY(!invalid.property(13).isValid());
337 QVERIFY(!invalid.property(engine.toStringHandle("aaa")).isValid());
338 }
339 {
340 QScriptValue object = engine.newObject();
341 QScriptValue property;
342
343 object.setProperty(13, property);
344 object.setProperty("aaa", property);
345 object.setProperty(engine.toStringHandle("aaa"), property);
346
347 QVERIFY(!object.property(13).isValid());
348 QVERIFY(!object.property("aaa").isValid());
349 QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid());
350 }
351 {
352 // Check if setting an invalid property works as deleteProperty.
353 QScriptValue object = engine.evaluate("o = {13: 0, 'aaa': 3, 'bbb': 1}");
354 QScriptValue property;
355
356 QVERIFY(object.property(13).isValid());
357 QVERIFY(object.property("aaa").isValid());
358 QVERIFY(object.property(engine.toStringHandle("aaa")).isValid());
359
360 object.setProperty(13, property);
361 object.setProperty("aaa", property);
362 object.setProperty(engine.toStringHandle("bbb"), property);
363
364 QVERIFY(!object.property(13).isValid());
365 QVERIFY(!object.property("aaa").isValid());
366 QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid());
367 }
368 {
369 QScriptValue object = engine.evaluate("new Object");
370 QVERIFY(object.isObject());
371 QScriptValue property = object.property("foo");
372 QVERIFY(!property.isValid());
373 property = QScriptValue(2);
374 object.setProperty("foo", property);
375 QVERIFY(object.property("foo").isNumber());
376 QVERIFY(object.property("foo").toNumber() == 2);
377 }
378 {
379 QScriptValue o1 = engine.evaluate("o1 = new Object; o1");
380 QScriptValue o2 = engine.evaluate("o2 = new Object; o2");
381 QVERIFY(engine.evaluate("o1.__proto__ = o2; o1.__proto__ === o2").toBool());
382 QVERIFY(engine.evaluate("o2.foo = 22; o1.foo == 22").toBool());
383 QVERIFY(o1.property("foo").toString() == "22");
384 o2.setProperty("foo", QScriptValue(&engine, 456.0));
385 QVERIFY(engine.evaluate("o1.foo == 456").toBool());
386 QVERIFY(o1.property("foo").isNumber());
387 }
388}
389
390void tst_QScriptValue::getPropertyResolveFlag()
391{
392 QScriptEngine engine;
393 QScriptValue object1 = engine.evaluate("o1 = new Object();");
394 QScriptValue object2 = engine.evaluate("o2 = new Object(); o1.__proto__ = o2; o2");
395 QScriptValue number(&engine, 456.0);
396 QVERIFY(object1.isObject());
397 QVERIFY(object2.isObject());
398 QVERIFY(number.isNumber());
399
400 object2.setProperty("propertyInPrototype", number);
401 QVERIFY(object2.property("propertyInPrototype").isNumber());
402 // default is ResolvePrototype
403 QCOMPARE(object1.property("propertyInPrototype").strictlyEquals(number), true);
404 QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolvePrototype)
405 .strictlyEquals(number), true);
406 QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolveLocal).isValid(), false);
407}
408
409void tst_QScriptValue::getSetProperty()
410{
411 QScriptEngine eng;
412
413 QScriptValue object = eng.newObject();
414
415 QScriptValue str = QScriptValue(&eng, "bar");
416 object.setProperty("foo", str);
417 QCOMPARE(object.property("foo").toString(), str.toString());
418
419 QScriptValue num = QScriptValue(&eng, 123.0);
420 object.setProperty("baz", num);
421 QCOMPARE(object.property("baz").toNumber(), num.toNumber());
422
423 QScriptValue strstr = QScriptValue("bar");
424 QCOMPARE(strstr.engine(), (QScriptEngine *)0);
425 object.setProperty("foo", strstr);
426 QCOMPARE(object.property("foo").toString(), strstr.toString());
427 QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine
428
429 QScriptValue numnum = QScriptValue(123.0);
430 object.setProperty("baz", numnum);
431 QCOMPARE(object.property("baz").toNumber(), numnum.toNumber());
432
433 QScriptValue inv;
434 inv.setProperty("foo", num);
435 QCOMPARE(inv.property("foo").isValid(), false);
436
437 QScriptValue array = eng.newArray();
438 array.setProperty(0, num);
439 QCOMPARE(array.property(0).toNumber(), num.toNumber());
440 QCOMPARE(array.property("0").toNumber(), num.toNumber());
441 QCOMPARE(array.property("length").toUInt32(), quint32(1));
442 array.setProperty(1, str);
443 QCOMPARE(array.property(1).toString(), str.toString());
444 QCOMPARE(array.property("1").toString(), str.toString());
445 QCOMPARE(array.property("length").toUInt32(), quint32(2));
446 array.setProperty("length", QScriptValue(&eng, 1));
447 QCOMPARE(array.property("length").toUInt32(), quint32(1));
448 QCOMPARE(array.property(1).isValid(), false);
449
450 // task 162051 -- detecting whether the property is an array index or not
451 QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123)));
452 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
453 QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QScriptValue(&eng, true)));
454 QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QScriptValue(&eng, false)));
455 QVERIFY(eng.evaluate("a[0]").isUndefined());
456 QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QScriptValue(&eng, 456)));
457 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
458 QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QScriptValue(&eng, true)));
459 QVERIFY(eng.evaluate("a[0]").isUndefined());
460 QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789)));
461 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1)));
462
463 // task 183072 -- 0x800000000 is not an array index
464 eng.evaluate("a = []; a[0x800000000] = 123");
465 QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0)));
466 QVERIFY(eng.evaluate("a[0]").isUndefined());
467 QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123)));
468
469 QScriptEngine otherEngine;
470 QScriptValue otherNum = QScriptValue(&otherEngine, 123);
471 QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: cannot set value created in a different engine");
472 object.setProperty("oof", otherNum);
473 QCOMPARE(object.property("oof").isValid(), false);
474
475 // test ResolveMode
476 QScriptValue object2 = eng.newObject();
477 object.setPrototype(object2);
478 QScriptValue num2 = QScriptValue(&eng, 456.0);
479 object2.setProperty("propertyInPrototype", num2);
480 // default is ResolvePrototype
481 QCOMPARE(object.property("propertyInPrototype")
482 .strictlyEquals(num2), true);
483 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolvePrototype)
484 .strictlyEquals(num2), true);
485 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveLocal)
486 .isValid(), false);
487 QEXPECT_FAIL("", "QScriptValue::ResolveScope is not implemented", Continue);
488 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveScope)
489 .strictlyEquals(num2), false);
490 QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull)
491 .strictlyEquals(num2), true);
492
493 // test property removal (setProperty(QScriptValue()))
494 QScriptValue object3 = eng.newObject();
495 object3.setProperty("foo", num);
496 QCOMPARE(object3.property("foo").strictlyEquals(num), true);
497 object3.setProperty("bar", str);
498 QCOMPARE(object3.property("bar").strictlyEquals(str), true);
499 object3.setProperty("foo", QScriptValue());
500 QCOMPARE(object3.property("foo").isValid(), false);
501 QCOMPARE(object3.property("bar").strictlyEquals(str), true);
502 object3.setProperty("foo", num);
503 QCOMPARE(object3.property("foo").strictlyEquals(num), true);
504 QCOMPARE(object3.property("bar").strictlyEquals(str), true);
505 object3.setProperty("bar", QScriptValue());
506 QCOMPARE(object3.property("bar").isValid(), false);
507 QCOMPARE(object3.property("foo").strictlyEquals(num), true);
508 object3.setProperty("foo", QScriptValue());
509 object3.setProperty("foo", QScriptValue());
510
511 eng.globalObject().setProperty("object3", object3);
512 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
513 .strictlyEquals(QScriptValue(&eng, false)), true);
514 object3.setProperty("foo", num);
515 QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
516 .strictlyEquals(QScriptValue(&eng, true)), true);
517 eng.globalObject().setProperty("object3", QScriptValue());
518 QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')")
519 .strictlyEquals(QScriptValue(&eng, false)), true);
520
521 eng.globalObject().setProperty("object", object);
522
523 // ReadOnly
524 object.setProperty("readOnlyProperty", num, QScriptValue::ReadOnly);
525 // QCOMPARE(object.propertyFlags("readOnlyProperty"), QScriptValue::ReadOnly);
526 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
527 eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty");
528 QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true);
529 // Should still be part of enumeration.
530 {
531 QScriptValue ret = eng.evaluate(
532 "found = false;"
533 "for (var p in object) {"
534 " if (p == 'readOnlyProperty') {"
535 " found = true; break;"
536 " }"
537 "} found");
538 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
539 }
540 // should still be deletable
541 {
542 QScriptValue ret = eng.evaluate("delete object.readOnlyProperty");
543 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
544 QCOMPARE(object.property("readOnlyProperty").isValid(), false);
545 }
546
547 // Undeletable
548 object.setProperty("undeletableProperty", num, QScriptValue::Undeletable);
549 // QCOMPARE(object.propertyFlags("undeletableProperty"), QScriptValue::Undeletable);
550 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
551 {
552 QScriptValue ret = eng.evaluate("delete object.undeletableProperty");
553 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), false);
554 QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true);
555 }
556 // should still be writable
557 eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1");
558 QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1);
559 // should still be part of enumeration
560 {
561 QScriptValue ret = eng.evaluate(
562 "found = false;"
563 "for (var p in object) {"
564 " if (p == 'undeletableProperty') {"
565 " found = true; break;"
566 " }"
567 "} found");
568 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
569 }
570 // should still be deletable from C++
571 object.setProperty("undeletableProperty", QScriptValue());
572 QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
573 QVERIFY(!object.property("undeletableProperty").isValid());
574 // QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
575 // QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
576
577 // SkipInEnumeration
578 object.setProperty("dontEnumProperty", num, QScriptValue::SkipInEnumeration);
579 // QCOMPARE(object.propertyFlags("dontEnumProperty"), QScriptValue::SkipInEnumeration);
580 QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true);
581 // should not be part of enumeration
582 {
583 QScriptValue ret = eng.evaluate(
584 "found = false;"
585 "for (var p in object) {"
586 " if (p == 'dontEnumProperty') {"
587 " found = true; break;"
588 " }"
589 "} found");
590 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, false)), true);
591 }
592 // should still be writable
593 eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1");
594 QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1);
595 // should still be deletable
596 {
597 QScriptValue ret = eng.evaluate("delete object.dontEnumProperty");
598 QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true);
599 QCOMPARE(object.property("dontEnumProperty").isValid(), false);
600 }
601
602 // change flags
603 object.setProperty("flagProperty", str);
604 // QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QScriptValue::PropertyFlags>(0));
605
606 object.setProperty("flagProperty", str, QScriptValue::ReadOnly);
607 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly);
608
609 // object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QScriptValue::SkipInEnumeration);
610 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
611
612 object.setProperty("flagProperty", str, QScriptValue::KeepExistingFlags);
613 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
614
615 object.setProperty("flagProperty", str, QScriptValue::UserRange);
616 // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::UserRange);
617
618 // flags of property in the prototype
619 {
620 QScriptValue object2 = eng.newObject();
621 object2.setPrototype(object);
622 // QCOMPARE(object2.propertyFlags("flagProperty", QScriptValue::ResolveLocal), 0);
623 // QCOMPARE(object2.propertyFlags("flagProperty"), QScriptValue::UserRange);
624 }
625
626 // using interned strings
627 QScriptString foo = eng.toStringHandle("foo");
628
629 object.setProperty(foo, QScriptValue());
630 QVERIFY(!object.property(foo).isValid());
631
632 object.setProperty(foo, num);
633 QVERIFY(object.property(foo).strictlyEquals(num));
634 QVERIFY(object.property("foo").strictlyEquals(num));
635 // QVERIFY(object.propertyFlags(foo) == 0);
636}
637
638void tst_QScriptValue::toStringSimple_data()
639{
640 QTest::addColumn<QString>("code");
641 QTest::addColumn<QString>("result");
642
643 QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello");
644 QTest::newRow("string utf") << QString::fromUtf8("'ąśćżźółńę'") << QString::fromUtf8("ąśćżźółńę");
645 QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5");
646 QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null");
647 QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false");
648 QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined");
649 QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]");
650}
651
652/* Test conversion to string from different JSC types */
653void tst_QScriptValue::toStringSimple()
654{
655 QFETCH(QString, code);
656 QFETCH(QString, result);
657
658 QScriptEngine engine;
659 QCOMPARE(engine.evaluate(code).toString(), result);
660}
661
662void tst_QScriptValue::copyConstructor_data()
663{
664 QScriptEngine engine;
665 QScriptValue nnumber(123);
666 QScriptValue nstring("ping");
667 QScriptValue number(engine.evaluate("1"));
668 QScriptValue string(engine.evaluate("'foo'"));
669 QScriptValue object(engine.evaluate("new Object"));
670 QScriptValue undefined(engine.evaluate("undefined"));
671 QScriptValue null(engine.evaluate("null"));
672
673 QTest::addColumn<QScriptValue>("value");
674 QTest::addColumn<QString>("result");
675
676 QTest::newRow("native number") << nnumber << QString::number(123);
677 QTest::newRow("native string") << nstring << QString("ping");
678 QTest::newRow("number") << number << QString::fromAscii("1");
679 QTest::newRow("string") << string << QString::fromAscii("foo");
680 QTest::newRow("object") << object << QString::fromAscii("[object Object]");
681 QTest::newRow("undefined") << undefined << QString::fromAscii("undefined");
682 QTest::newRow("null") << null << QString::fromAscii("null");
683}
684
685void tst_QScriptValue::copyConstructor()
686{
687 QFETCH(QScriptValue, value);
688 QFETCH(QString, result);
689
690 QVERIFY(value.isValid());
691 QScriptValue tmp(value);
692 QVERIFY(tmp.isValid());
693 QCOMPARE(tmp.toString(), result);
694}
695
696void tst_QScriptValue::assignOperator_data()
697{
698 copyConstructor_data();
699}
700
701void tst_QScriptValue::assignOperator()
702{
703 QFETCH(QScriptValue, value);
704 QFETCH(QString, result);
705
706 QScriptValue tmp;
707 tmp = value;
708 QVERIFY(tmp.isValid());
709 QCOMPARE(tmp.toString(), result);
710}
711
712/* Test internal data sharing between a diffrenet QScriptValue. */
713void tst_QScriptValue::dataSharing()
714{
715 QScriptEngine engine;
716 QScriptValue v1;
717 QScriptValue v2(v1);
718
719 v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid.
720 QVERIFY(v1.isValid());
721 QVERIFY(!v2.isValid());
722
723 v2 = v1; // v1 == 1; v2 == 1.
724 QVERIFY(v1.isValid());
725 QVERIFY(v2.isValid());
726
727 v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1.
728 QVERIFY(v1.isValid());
729 QVERIFY(v2.isValid());
730 QVERIFY(v2.toString() != v1.toString());
731
732 // TODO add object manipulation (v1 and v2 point to the same object).
733}
734
735void tst_QScriptValue::constructors_data()
736{
737 QScriptEngine engine;
738
739 QTest::addColumn<QScriptValue>("value");
740 QTest::addColumn<QString>("string");
741 QTest::addColumn<bool>("valid");
742 QTest::addColumn<bool>("object");
743
744 QTest::newRow("invalid") << QScriptValue() << QString() << false << false;
745 QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false;
746 QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false;
747 QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false;
748 QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false;
749 QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true;
750 QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false;
751 QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false;
752}
753
754void tst_QScriptValue::constructors()
755{
756 QFETCH(QScriptValue, value);
757 QFETCH(QString, string);
758 QFETCH(bool, valid);
759 QFETCH(bool, object);
760
761 QCOMPARE(value.isValid(), valid);
762 QCOMPARE(value.toString(), string);
763 QCOMPARE(value.isObject(), object);
764}
765
766void tst_QScriptValue::call()
767{
768 QScriptEngine engine;
769 QScriptValue ping = engine.evaluate("( function() {return 'ping';} )");
770 QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )");
771 QScriptValue one(1);
772 QScriptValue five(5);
773 QScriptValue result;
774
775 QVERIFY(one.isValid());
776 QVERIFY(five.isValid());
777
778 QVERIFY(ping.isValid());
779 QVERIFY(ping.isFunction());
780 result = ping.call();
781 QVERIFY(result.isValid());
782 QCOMPARE(result.toString(), QString::fromUtf8("ping"));
783
784 QVERIFY(incr.isValid());
785 QVERIFY(incr.isFunction());
786 result = incr.call(QScriptValue(), QScriptValueList() << one);
787 QVERIFY(result.isValid());
788 QCOMPARE(result.toString(), QString("2"));
789
790 QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6"));
791
792 QVERIFY(incr.call().isValid()); // Exception.
793}
794
795void tst_QScriptValue::getSetPrototype()
796{
797 QScriptEngine engine;
798 QScriptValue object = engine.evaluate("new Object()");
799 QScriptValue object2 = engine.evaluate("new Object()");
800 object2.setPrototype(object);
801 QCOMPARE(object2.prototype().strictlyEquals(object), true);
802
803 QScriptValue inv;
804 inv.setPrototype(object);
805 QCOMPARE(inv.prototype().isValid(), false);
806
807 QScriptEngine otherEngine;
808 QScriptValue object3 = otherEngine.evaluate("new Object()");
809 QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
810 object2.setPrototype(object3);
811 QCOMPARE(object2.prototype().strictlyEquals(object), true);
812
813 // cyclic prototypes
814 {
815 QScriptValue ret = engine.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
816 QCOMPARE(ret.isError(), true);
817 QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
818 }
819 {
820 QScriptValue ret = engine.evaluate("p.__proto__ = { }");
821 QCOMPARE(ret.isError(), false);
822 }
823
824 QScriptValue old = object.prototype();
825 QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
826 object.setPrototype(object);
827 QCOMPARE(object.prototype().strictlyEquals(old), true);
828
829 object2.setPrototype(object);
830 QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
831 object.setPrototype(object2);
832 QCOMPARE(object.prototype().strictlyEquals(old), true);
833}
834
835void tst_QScriptValue::toObjectSimple()
836{
837 QScriptEngine eng;
838
839 QScriptValue undefined = eng.undefinedValue();
840 QCOMPARE(undefined.toObject().isValid(), false);
841 QScriptValue null = eng.nullValue();
842 QCOMPARE(null.toObject().isValid(), false);
843 QCOMPARE(QScriptValue().toObject().isValid(), false);
844
845 QScriptValue falskt = QScriptValue(&eng, false);
846 {
847 QScriptValue tmp = falskt.toObject();
848 QCOMPARE(tmp.isObject(), true);
849 QCOMPARE(falskt.isObject(), false);
850 QCOMPARE(tmp.toNumber(), falskt.toNumber());
851 }
852
853 QScriptValue sant = QScriptValue(&eng, true);
854 {
855 QScriptValue tmp = sant.toObject();
856 QCOMPARE(tmp.isObject(), true);
857 QCOMPARE(sant.isObject(), false);
858 QCOMPARE(tmp.toNumber(), sant.toNumber());
859 }
860
861 QScriptValue number = QScriptValue(&eng, 123.0);
862 {
863 QScriptValue tmp = number.toObject();
864 QCOMPARE(tmp.isObject(), true);
865 QCOMPARE(number.isObject(), false);
866 QCOMPARE(tmp.toNumber(), number.toNumber());
867 }
868
869 QScriptValue str = QScriptValue(&eng, QString("ciao"));
870 {
871 QScriptValue tmp = str.toObject();
872 QCOMPARE(tmp.isObject(), true);
873 QCOMPARE(str.isObject(), false);
874 QCOMPARE(tmp.toString(), str.toString());
875 }
876
877
878 QScriptValue object = eng.evaluate("new Object");
879 {
880 QScriptValue tmp = object.toObject();
881 QVERIFY(tmp.strictlyEquals(object));
882 QCOMPARE(tmp.isObject(), true);
883 }
884
885
886 // V2 constructors: in this case, you have to use QScriptEngine::toObject()
887 {
888 QScriptValue undefined = QScriptValue(QScriptValue::UndefinedValue);
889 QVERIFY(!undefined.toObject().isValid());
890 QVERIFY(!eng.toObject(undefined).isValid());
891 QVERIFY(!undefined.engine());
892
893 QScriptValue null = QScriptValue(QScriptValue::NullValue);
894 QVERIFY(!null.toObject().isValid());
895 QVERIFY(!eng.toObject(null).isValid());
896 QVERIFY(!null.engine());
897
898 QScriptValue falskt = QScriptValue(false);
899 QVERIFY(!falskt.toObject().isValid());
900 QCOMPARE(falskt.isObject(), false);
901 QVERIFY(!falskt.engine());
902 {
903 QScriptValue tmp = eng.toObject(falskt);
904 QVERIFY(tmp.isObject());
905 QVERIFY(tmp.toBool());
906 QVERIFY(!falskt.isObject());
907 }
908
909 QScriptValue sant = QScriptValue(true);
910 QVERIFY(!sant.toObject().isValid());
911 QCOMPARE(sant.isObject(), false);
912 QVERIFY(!sant.engine());
913 {
914 QScriptValue tmp = eng.toObject(sant);
915 QVERIFY(tmp.isObject());
916 QVERIFY(tmp.toBool());
917 QVERIFY(!sant.isObject());
918 }
919
920 QScriptValue number = QScriptValue(123.0);
921 QVERIFY(!number.toObject().isValid());
922 QVERIFY(!number.engine());
923 QCOMPARE(number.isObject(), false);
924 {
925 QScriptValue tmp = eng.toObject(number);
926 QVERIFY(tmp.isObject());
927 QCOMPARE(tmp.toInt32(), number.toInt32());
928 QVERIFY(!number.isObject());
929 }
930
931 QScriptValue str = QScriptValue(QString::fromLatin1("ciao"));
932 QVERIFY(!str.toObject().isValid());
933 QVERIFY(!str.engine());
934 QCOMPARE(str.isObject(), false);
935 {
936 QScriptValue tmp = eng.toObject(str);
937 QVERIFY(tmp.isObject());
938 QCOMPARE(tmp.toString(), QString::fromLatin1("ciao"));
939 QVERIFY(!str.isObject());
940 }
941 }
942}
943
944void tst_QScriptValue::setProperty_data()
945{
946 QTest::addColumn<QScriptValue>("property");
947 QTest::addColumn<int>("flag");
948
949 QTest::newRow("int + keepExistingFlags") << QScriptValue(123456) << static_cast<int>(QScriptValue::KeepExistingFlags);
950 QTest::newRow("int + undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::Undeletable);
951 QTest::newRow("int + readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly);
952 QTest::newRow("int + readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable);
953 QTest::newRow("int + skipInEnumeration") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration);
954 QTest::newRow("int + skipInEnumeration|readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
955 QTest::newRow("int + skipInEnumeration|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
956 QTest::newRow("int + skipInEnumeration|readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly | QScriptValue::Undeletable);
957}
958
959void tst_QScriptValue::setProperty()
960{
961 QFETCH(QScriptValue, property);
962 QFETCH(int, flag);
963 QScriptValue::PropertyFlags flags = static_cast<QScriptValue::PropertyFlag>(flag);
964
965 QScriptEngine engine;
966 QScriptValue object = engine.evaluate("o = new Object; o");
967 QScriptValue proto = engine.evaluate("p = new Object; o.__proto__ = p; p");
968 engine.evaluate("o.defined1 = 1");
969 engine.evaluate("o.defined2 = 1");
970 engine.evaluate("o[5] = 1");
971 engine.evaluate("p.overloaded1 = 1");
972 engine.evaluate("o.overloaded1 = 2");
973 engine.evaluate("p[6] = 1");
974 engine.evaluate("o[6] = 2");
975 engine.evaluate("p.overloaded2 = 1");
976 engine.evaluate("o.overloaded2 = 2");
977 engine.evaluate("p.overloaded3 = 1");
978 engine.evaluate("o.overloaded3 = 2");
979 engine.evaluate("p[7] = 1");
980 engine.evaluate("o[7] = 2");
981 engine.evaluate("p.overloaded4 = 1");
982 engine.evaluate("o.overloaded4 = 2");
983
984 // tries to set undefined property directly on object.
985 object.setProperty(QString::fromAscii("undefined1"), property, flags);
986 QVERIFY(engine.evaluate("o.undefined1").strictlyEquals(property));
987 object.setProperty(engine.toStringHandle("undefined2"), property, flags);
988 QVERIFY(object.property("undefined2").strictlyEquals(property));
989 object.setProperty(4, property, flags);
990 QVERIFY(object.property(4).strictlyEquals(property));
991
992 // tries to set defined property directly on object
993 object.setProperty("defined1", property, flags);
994 QVERIFY(engine.evaluate("o.defined1").strictlyEquals(property));
995 object.setProperty(engine.toStringHandle("defined2"), property, flags);
996 QVERIFY(object.property("defined2").strictlyEquals(property));
997 object.setProperty(5, property, flags);
998 QVERIFY(object.property(5).strictlyEquals(property));
999
1000 // tries to set overloaded property directly on object
1001 object.setProperty("overloaded1", property, flags);
1002 QVERIFY(engine.evaluate("o.overloaded1").strictlyEquals(property));
1003 object.setProperty(engine.toStringHandle("overloaded2"), property, flags);
1004 QVERIFY(object.property("overloaded2").strictlyEquals(property));
1005 object.setProperty(6, property, flags);
1006 QVERIFY(object.property(6).strictlyEquals(property));
1007
1008 // tries to set overloaded property directly on prototype
1009 proto.setProperty("overloaded3", property, flags);
1010 QVERIFY(!engine.evaluate("o.overloaded3").strictlyEquals(property));
1011 proto.setProperty(engine.toStringHandle("overloaded4"), property, flags);
1012 QVERIFY(!object.property("overloaded4").strictlyEquals(property));
1013 proto.setProperty(7, property, flags);
1014 QVERIFY(!object.property(7).strictlyEquals(property));
1015
1016 // tries to set undefined property directly on prototype
1017 proto.setProperty("undefined3", property, flags);
1018 QVERIFY(engine.evaluate("o.undefined3").strictlyEquals(property));
1019 proto.setProperty(engine.toStringHandle("undefined4"), property, flags);
1020 QVERIFY(object.property("undefined4").strictlyEquals(property));
1021 proto.setProperty(8, property, flags);
1022 QVERIFY(object.property(8).strictlyEquals(property));
1023
1024 bool readOnly = flags & QScriptValue::ReadOnly;
1025 bool skipInEnumeration = flags & QScriptValue::SkipInEnumeration;
1026 bool undeletable = flags & QScriptValue::Undeletable;
1027
1028 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').writable").toBool());
1029 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1030 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1031 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1032 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1033 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').writable").toBool());
1034 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1035 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1036 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1037 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1038 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').writable").toBool());
1039 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1040 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1041 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1042 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1043 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').writable").toBool());
1044 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').writable").toBool());
1045 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').writable").toBool());
1046 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').writable").toBool());
1047 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').writable").toBool());
1048 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').writable").toBool());
1049 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1050 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1051 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1052 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1053 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').writable").toBool());
1054 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1055 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1056 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1057 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1058 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').writable").toBool());
1059 QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool());
1060 QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool());
1061 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1062 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1063 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1064 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1065 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').writable").toBool());
1066 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1067 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1068 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1069 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1070 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').writable").toBool());
1071 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1072 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1073 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1074 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1075 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').writable").toBool());
1076 QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1077 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1078 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1079 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1080 QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').writable").toBool());
1081 QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded3').writable").toBool());
1082 QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded4').writable").toBool());
1083
1084 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').configurable").toBool());
1085 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1086 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1087 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1088 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1089 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').configurable").toBool());
1090 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1091 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1092 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1093 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1094 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').configurable").toBool());
1095 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1096 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1097 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1098 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1099 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').configurable").toBool());
1100 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').configurable").toBool());
1101 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').configurable").toBool());
1102 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').configurable").toBool());
1103 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').configurable").toBool());
1104 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').configurable").toBool());
1105 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1106 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1107 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1108 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1109 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').configurable").toBool());
1110 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1111 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1112 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1113 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1114 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').configurable").toBool());
1115 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1116 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1117 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1118 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1119 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').configurable").toBool());
1120 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1121 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1122 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1123 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1124 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').configurable").toBool());
1125 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded1').configurable").toBool());
1126 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded2').configurable").toBool());
1127 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded3').configurable").toBool());
1128 QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded4').configurable").toBool());
1129 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1130 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1131 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1132 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1133 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').configurable").toBool());
1134 QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1135 QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1136 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1137 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1138 QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').configurable").toBool());
1139
1140 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '4').enumerable").toBool());
1141 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1142 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1143 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1144 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1145 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '5').enumerable").toBool());
1146 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1147 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1148 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1149 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1150 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '6').enumerable").toBool());
1151 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1152 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1153 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1154 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1155 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '7').enumerable").toBool());
1156 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '8').enumerable").toBool());
1157 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined1').enumerable").toBool());
1158 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined2').enumerable").toBool());
1159 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined3').enumerable").toBool());
1160 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined4').enumerable").toBool());
1161 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1162 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1163 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1164 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1165 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded1').enumerable").toBool());
1166 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1167 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1168 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1169 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1170 QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded2').enumerable").toBool());
1171 QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded1')").toBool());
1172 QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded2')").toBool());
1173 QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded3')").toBool());
1174 QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded4')").toBool());
1175 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1176 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1177 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1178 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1179 QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded3')").toBool());
1180 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1181 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1182 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1183 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1184 QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded4')").toBool());
1185 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1186 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1187 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1188 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1189 QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined1')").toBool());
1190 QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1191 QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1192 QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1193 QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1194 QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined2')").toBool());
1195}
1196
1197void tst_QScriptValue::propertyFlag_data()
1198{
1199 QTest::addColumn<QString>("name");
1200 QTest::addColumn<int>("flag");
1201
1202 QTest::newRow("?Cr@jzi!%$") << "?Cr@jzi!%$" << static_cast<int>(0);
1203 QTest::newRow("ReadOnly") << "ReadOnly" << static_cast<int>(QScriptValue::ReadOnly);
1204 QTest::newRow("Undeletable") << "Undeletable" << static_cast<int>(QScriptValue::Undeletable);
1205 QTest::newRow("SkipInEnumeration") << "SkipInEnumeration" << static_cast<int>(QScriptValue::SkipInEnumeration);
1206 QTest::newRow("ReadOnly | Undeletable") << "ReadOnly_Undeletable" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable);
1207 QTest::newRow("ReadOnly | SkipInEnumeration") << "ReadOnly_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration);
1208 QTest::newRow("Undeletable | SkipInEnumeration") << "Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
1209 QTest::newRow("ReadOnly | Undeletable | SkipInEnumeration") << "ReadOnly_Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
1210}
1211
1212void tst_QScriptValue::propertyFlag()
1213{
1214 QScriptEngine engine;
1215 QFETCH(QString, name);
1216 QFETCH(int, flag);
1217 const QScriptString nameHandle = engine.toStringHandle(name);
1218 const QString protoName = "proto" + name;
1219 const QScriptString protoNameHandle = engine.toStringHandle(protoName);
1220
1221 QScriptValue proto = engine.newObject();
1222 QScriptValue object = engine.newObject();
1223 object.setPrototype(proto);
1224
1225 proto.setProperty(protoName, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
1226 object.setProperty(name, QScriptValue(124816), QScriptValue::PropertyFlag(flag));
1227
1228 // Check using QString name
1229 QCOMPARE(object.propertyFlags(name), QScriptValue::PropertyFlag(flag));
1230 QCOMPARE(object.propertyFlags(protoName, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
1231 QVERIFY(!object.propertyFlags(protoName, QScriptValue::ResolveLocal));
1232
1233 // Check using QScriptString name
1234 QCOMPARE(object.propertyFlags(nameHandle), QScriptValue::PropertyFlag(flag));
1235 QCOMPARE(object.propertyFlags(protoNameHandle, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag));
1236 QVERIFY(!object.propertyFlags(protoNameHandle, QScriptValue::ResolveLocal));
1237}
1238
1239void tst_QScriptValue::globalObjectChanges()
1240{
1241 // API functionality shouldn't depend on Global Object.
1242 QScriptEngine engine;
1243 QScriptValue array = engine.newArray();
1244 QScriptValue error = engine.evaluate("new Error");
1245 QScriptValue object = engine.newObject();
1246
1247 object.setProperty("foo", 512);
1248
1249 // Remove properties form global object.
1250 engine.evaluate("delete Object; delete Error; delete Array;");
1251
1252 QVERIFY(array.isArray());
1253 QVERIFY(error.isError());
1254 QVERIFY(object.isObject());
1255
1256 QVERIFY(object.property("foo").isValid());
1257 QVERIFY(object.property("foo", QScriptValue::ResolveLocal).isValid());
1258 object.setProperty("foo", QScriptValue());
1259 QVERIFY(!object.property("foo").isValid());
1260 QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid());
1261}
1262
1263void tst_QScriptValue::assignAndCopyConstruct_data()
1264{
1265 QTest::addColumn<QScriptValue>("value");
1266 if (m_engine)
1267 delete m_engine;
1268 m_engine = new QScriptEngine;
1269 // Copy & assign code is the same for all types, so it is enough to check only a few value.
1270 for (unsigned i = 0; i < 10; ++i) {
1271 QPair<QString, QScriptValue> testcase = initScriptValues(i);
1272 QTest::newRow(testcase.first.toAscii().constData()) << testcase.second;
1273 }
1274}
1275
1276void tst_QScriptValue::assignAndCopyConstruct()
1277{
1278 QFETCH(QScriptValue, value);
1279 QScriptValue copy(value);
1280 QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Abort);
1281 QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Abort);
1282 QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber()));
1283 QCOMPARE(copy.engine(), value.engine());
1284
1285 QScriptValue assigned = copy;
1286 QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber()));
1287 QCOMPARE(assigned.engine(), assigned.engine());
1288
1289 QScriptValue other(!value.toBool());
1290 assigned = other;
1291 QVERIFY(!assigned.strictlyEquals(copy));
1292 QVERIFY(assigned.strictlyEquals(other));
1293 QCOMPARE(assigned.engine(), other.engine());
1294}
1295
1296QTEST_MAIN(tst_QScriptValue)