2 // Copyright (C) 2005, 2006, 2007, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 // Test case for Object ActionScript class
21 // compile this test case with Ming makeswf, and then
22 // execute it like this gnash -1 -r 0 -v out.swf
28 // Test things in Class Object (swf5~swf8)
29 check_equals
(typeof(Object), 'function');
30 check_equals
(typeof(Object.prototype
), 'object');
31 check_equals
(typeof(Object.constructor
), 'function');
32 #if OUTPUT_VERSION
== 5
33 check_equals
(typeof(Object.__proto__
), 'undefined');
34 // make Object.__proto__ visible in swf5
35 ASSetPropFlags
(Object, null, 8, 128 + 1);
37 check_equals
(typeof(Object.__proto__
), 'object');
39 // registerClass is a public static function of Object
40 check_equals
(typeof(Object.registerClass
), 'function');
41 check_equals
(Object.prototype
.registerClass
, undefined);
43 // Test things in Object.prototype (swf5~swf8)
44 check_equals
(typeof(Object.prototype
.toString
), 'function');
45 check_equals
(typeof(Object.prototype
.toLocaleString
), 'function');
46 check_equals
(typeof(Object.prototype
.valueOf
), 'function');
47 check_equals
(typeof(Object.prototype
.constructor
), 'function');
48 #if OUTPUT_VERSION
== 5
49 check_equals
(typeof(Object.prototype
.addProperty
), 'undefined');
50 check_equals
(typeof(Object.prototype
.watch
), 'undefined');
51 check_equals
(typeof(Object.prototype
.unwatch
), 'undefined');
52 check_equals
(typeof(Object.prototype
.isPropertyEnumerable
), 'undefined');
53 check_equals
(typeof(Object.prototype
.isPrototypeOs
), 'undefined');
54 check_equals
(typeof(Object.prototype
.hasOwnProperty
), 'undefined');
55 // make functions above visible
56 ASSetPropFlags
(Object.prototype
, null, 8, 128 + 1);
58 // These functions are visible now even in swf5 (swf5 ~ swf8)
59 check_equals
(typeof(Object.prototype
.addProperty
), 'function');
60 check_equals
(typeof(Object.prototype
.watch
), 'function');
61 check_equals
(typeof(Object.prototype
.unwatch
), 'function');
62 check_equals
(typeof(Object.prototype
.isPropertyEnumerable
), 'function');
63 check_equals
(typeof(Object.prototype
.isPrototypeOf
), 'function');
64 check_equals
(typeof(Object.prototype
.hasOwnProperty
), 'function');
66 check_equals
(Object.prototype
.constructor
, Object);
67 check_equals
(typeof(Object.prototype
.toString
.constructor
), 'function');
69 #if OUTPUT_VERSION
> 5
70 // Function Object only exists in swf6 and above
71 check_equals
(Object.prototype
.toString
.constructor
, Function);
73 check_equals
(typeof(Function), 'undefined');
75 check_equals
(Object.prototype
.prototype
, undefined);
77 // The bug below (no end in the inheritance chain) triggers endless
78 // recursions during run of the trace_properties() function defined
79 // in trace_properties.as from swfdec testsuite.
80 // WE WANT THIS FIXED !!
81 check_equals
(Object.prototype
.__proto__
, undefined);
82 check
(!Object.prototype
.hasOwnProperty
("__proto__"));
85 #if OUTPUT_VERSION
> 5
87 // Through test of existance of methods!
89 check
(Object.hasOwnProperty
('__proto__'));
92 check_equals
(O
, Object);
94 // found 4 methods in Object
95 check
(O
.hasOwnProperty
('__proto__'));
96 check
(O
.hasOwnProperty
('registerClass'));
97 check
(O
.hasOwnProperty
('constructor'));
98 check
(O
.hasOwnProperty
('prototype'));
100 // fount 4 methods in Object.__proto__
101 check
(O
.__proto__
.hasOwnProperty
('__proto__'));
102 check
(O
.__proto__
.hasOwnProperty
('apply'));
103 check
(O
.__proto__
.hasOwnProperty
('call'));
104 check
(O
.__proto__
.hasOwnProperty
('constructor'));
106 check
(O
.__proto__
!= Object.prototype
);
107 check
(O
.__proto__
.__proto__
== Object.prototype
);
109 // found 3 methods in Object.constructor
110 check
(O
.constructor
.hasOwnProperty
('__proto__'));
111 check
(O
.constructor
.hasOwnProperty
('constructor'));
112 check
(O
.constructor
.hasOwnProperty
('prototype'));
114 // found 9 methods in Object.prototype
115 check
(O
.prototype
.hasOwnProperty
('addProperty'));
116 check
(O
.prototype
.hasOwnProperty
('constructor'));
117 check
(O
.prototype
.hasOwnProperty
('hasOwnProperty'));
118 check
(O
.prototype
.hasOwnProperty
('isPropertyEnumerable'));
119 check
(O
.prototype
.hasOwnProperty
('isPrototypeOf'));
120 check
(O
.prototype
.hasOwnProperty
('toString'));
121 check
(O
.prototype
.hasOwnProperty
('valueOf'));
122 check
(O
.prototype
.hasOwnProperty
('unwatch'));
123 check
(O
.prototype
.hasOwnProperty
('watch'));
125 // found 3 methods in Object.prototype.constructor
126 check
(O
.prototype
.constructor
.hasOwnProperty
('__proto__'));
127 check
(O
.prototype
.constructor
.hasOwnProperty
('constructor'));
128 check
(O
.prototype
.constructor
.hasOwnProperty
('prototype'));
130 check_equals
(O
.prototype
.constructor
, Object);
131 check_equals
(O
.constructor
, Function);
133 check_equals
(typeof(Object.prototype
.addProperty
), 'function');
134 check_equals
(typeof(Object.prototype
.hasOwnProperty
), 'function');
135 check_equals
(typeof(Object.prototype
.isPropertyEnumerable
), 'function');
136 check_equals
(typeof(Object.prototype
.isPrototypeOf
), 'function');
137 check_equals
(typeof(Object.prototype
.watch
), 'function');
138 check_equals
(typeof(Object.prototype
.unwatch
), 'function');
141 // Test Object creation using 'new'
142 var obj
= new Object; // uses SWFACTION_NEWOBJECT
143 check
(obj
!= undefined);
144 check_equals
(typeof(obj
), "object");
146 check_equals
(obj
.__proto__
, Object.prototype
);
147 check_equals
(typeof(obj
.prototype
), 'undefined');
148 check_equals
(typeof(obj
.__proto__
), 'object');
150 #if OUTPUT_VERSION
== 5
151 check
(obj
.__constructor__
== undefined);
152 // make obj.__constructor__ visible
153 ASSetPropFlags
(obj
, null, 8, 128 + 1);
154 check
(obj
.__constructor__
== Object);
156 check
(obj
.__constructor__
== Object);
159 check
(obj
.constructor
== Object);
160 check
(Object.prototype
.constructor
== Object);
161 check
(obj
.__proto__
.constructor
== Object);
163 // Test instantiated Object methods
164 check_equals
(typeof(obj
.toString
), 'function');
165 check_equals
(typeof(obj
.valueOf
), 'function');
166 check_equals
(typeof(obj
.addProperty
), 'function');
168 check
(Object.hasOwnProperty
('constructor'));
169 #if OUTPUT_VERSION
== 6
170 check
(obj
.hasOwnProperty
('constructor'));
171 #elif OUTPUT_VERSION
> 6
172 // seems swf7 and above are different.
173 check
(!obj
.hasOwnProperty
('constructor'));
176 check
(obj
.hasOwnProperty
('__constructor__'));
178 // Test instantiated Object members
180 check
(obj
.member
== 1)
181 check_equals
(typeof(obj
.toString
()), 'string');
182 check_equals
(obj
.toString
(), '[object Object]');
183 check_equals
(typeof(obj
.valueOf
()), 'object');
184 check_equals
(obj
.valueOf
(), obj
);
186 // Test Object creation using literal initialization
187 var obj2
= { member
:1 }; // uses SWFACTION_INITOBJECT
188 check_equals
(typeof(obj2
), "object");
189 check_equals
(typeof(obj2
.__proto__
), 'object');
190 check_equals
(obj2
.__proto__
, Object.prototype
);
191 check_equals
(obj2
.__proto__
.constructor
, Object);
192 check_equals
(typeof(obj2
.prototype
), 'undefined');
195 // Test initialized object members
196 check
( obj2
.member
== 1 )
198 // Test Object creation using initializing constructor
199 var obj3
= new Object({ member
:1 });
200 check
(obj3
!= undefined);
201 check
(typeof(obj3
) == "object");
202 check
(obj3
.__proto__
.constructor
== Object);
204 // Test initialized object members
205 check
( obj3
.member
!= undefined );
206 check
( obj3
.member
== 1 );
208 // Test after-initialization members set/get
210 check
( obj3
.member2
!= undefined );
211 check
( obj3
.member2
== 3 );
213 //----------------------
215 //----------------------
217 var copy
= new Object(obj3
);
218 check_equals
( copy
.member2
, 3 );
220 check_equals
( copy
.test
, 4 );
221 check_equals
( obj3
.test
, 4 );
222 check
(copy
.__proto__
.constructor
== Object);
224 o
= new Object("hello");
225 check_equals
(o
.toString
(), "hello");
226 check_equals
(o
.valueOf
(), "hello");
229 check_equals
(o
.toString
(), "5");
230 check_equals
(o
.valueOf
(), 5);
232 o
= new Object(undefined);
233 check_equals
(o
.toString
(), "[object Object]");
234 check_equals
(typeof(o
.valueOf
()), "object");
235 check_equals
(o
.valueOf
(), o
);
237 o
= new Object(null);
238 check_equals
(o
.toString
(), "[object Object]");
239 check_equals
(typeof(o
.valueOf
()), "object");
240 check_equals
(o
.valueOf
(), o
);
242 //---------------------------------------------
243 // Test addProperty / hasOwnProperty (SWF6 up)
244 //---------------------------------------------
246 // Object.addProperty wasn't in SWF5
247 #if OUTPUT_VERSION
> 5
249 // the 'getter' function
254 // the 'setter' function
259 // add the "len" property
260 var ret
= obj3
.addProperty
("len", getLen
, setLen
);
261 check_equals
(ret
, true);
263 // toString is not obj3 "own" property, but it's inherited !
264 check_equals
(typeof(obj3
.toString
), 'function');
265 ownPropertyCheck
= obj3
.hasOwnProperty
("toString");
266 check_equals
(typeof(ownPropertyCheck
), 'boolean');
267 check
(!ownPropertyCheck
);
269 // 'member' is an obj3 "own" member (not inherited)
270 ownPropertyCheck
= obj3
.hasOwnProperty
("member");
271 check_equals
(typeof(ownPropertyCheck
), 'boolean');
272 check
(ownPropertyCheck
);
274 // 'len' is an obj3 "own" property (not inherited)
275 ownPropertyCheck
= obj3
.hasOwnProperty
("len");
276 check_equals
(typeof(ownPropertyCheck
), 'boolean');
277 check
(ownPropertyCheck
);
279 check_equals
(obj3
.len
, undefined);
281 check_equals
(obj3
.len
, 3);
283 check_equals
(obj3
._len
, 5);
284 check_equals
(obj3
.len
, 5);
286 // TODO: try omitting the "setter" argument
287 var ret
= obj3
.addProperty
("len2", getLen
);
288 check_equals
(ret
, false);
289 check_equals
(obj3
.len2
, undefined);
291 check_equals
(obj3
.len2
, 'test');
293 obj3
.__proto__
= undefined;
294 check_equals
(typeof(obj3
), "object");
295 check_equals
(typeof(obj3
.__proto__
), 'undefined');
296 check_equals
(obj3
, undefined);
298 // Use name of an existing property
302 function test_get
() { _root
.test_get_calls
++; return this.test
; }
303 function test_set
(v
) { this.test
=v
; _root
.test_set_calls
++; }
304 test_set_calls
=test_get_calls
=0;
305 r
= o
.addProperty
("test", test_get
, test_set
);
307 check_equals
(test_set_calls
, 0);
308 check_equals
(test_get_calls
, 0);
309 test_set_calls
=test_get_calls
=0;
311 check_equals
(test_set_calls
, 0);
312 #if OUTPUT_VERSION
< 7
313 check_equals
(test_get_calls
, 1);
315 xcheck_equals
(test_get_calls
, 65); // urgh ! :)
317 check_equals
(v
, 5); // underlying value was initializied to existing prop
318 test_set_calls
=test_get_calls
=0;
319 o
.test
= 16; // should change underlying as well I guess
320 check_equals
(test_get_calls
, 0);
321 #if OUTPUT_VERSION
< 7
322 check_equals
(test_set_calls
, 1);
324 xcheck_equals
(test_set_calls
, 65); // urgh ! :)
326 test_set_calls
=test_get_calls
=0;
327 r
= o
.addProperty
("test", test_get
, test_set
);
329 check_equals
(test_get_calls
, 0); // didn't invoke the former getter..
330 check_equals
(test_set_calls
, 0); // .. to fetch underlying var
332 test_set_calls
=test_get_calls
=0;
334 // got underlying value from previous getter-setter
336 #if OUTPUT_VERSION
< 7
337 check_equals
(test_get_calls
, 1);
339 xcheck_equals
(test_get_calls
, 65); // urgh ! :)
341 check_equals
(test_set_calls
, 0);
343 // Existing property higher in inheritance chain
349 check_equals
(o
.test
, 19);
350 r
= o
.addProperty
("test", test_get
, test_set
);
353 check_equals
(v
, undefined); // but not existing prop from inheritance chain
355 // Existing native property
357 o
= createEmptyMovieClip
("hello", 10);
358 check_equals
(o
._target
, "/hello");
359 function target_get
() { _root
.target_get_calls
++; return this._target
; }
360 function target_set
(v
) { this._target
=v
; _root
.target_set_calls
++; }
361 target_get_calls
=target_set_calls
=0;
362 ret
= o
.addProperty
("_target", target_get
, target_set
);
363 check_equals
(ret
, true);
364 check_equals
(_root
.target_get_calls
, 0);
365 check_equals
(_root
.target_set_calls
, 0);
366 check_equals
(typeof(o
._target
), "undefined"); // native getter-setter don't get initialized with underlying value
368 // Check return value.
369 ret
= o
.addProperty
("", target_get
, target_get
);
370 check_equals
(ret
, false);
372 ret
= o
.addProperty
("frog", 7, target_get
);
373 check_equals
(ret
, false);
375 ret
= o
.addProperty
("frog", "string", target_get
);
376 check_equals
(ret
, false);
378 ret
= o
.addProperty
("frog", target_get
, target_get
);
379 check_equals
(ret
, true);
381 ret
= o
.addProperty
("frog", target_get
, target_get
);
382 check_equals
(ret
, true);
384 ret
= o
.addProperty
("frog", target_get
, undefined);
385 check_equals
(ret
, false);
387 ret
= o
.addProperty
("frog", target_get
, null);
388 check_equals
(ret
, true);
390 ret
= o
.addProperty
("frog", target_get
, null, "extra arg");
391 check_equals
(ret
, true);
393 // Try property inheritance
395 var proto
= new Object();
396 check
(proto
.addProperty
("len", getLen
, setLen
));
397 var inh1
= new Object();
398 inh1
.__proto__
= proto
;
399 var inh2
= new Object();
400 inh2
.__proto__
= proto
;
401 check_equals
(inh1
._len
, undefined);
402 check_equals
(inh2
._len
, undefined);
405 check_equals
(inh1
._len
, 4);
406 check_equals
(inh2
._len
, 9);
407 check_equals
(proto
._len
, undefined);
410 check_equals
(inh1
.len
, 5);
411 check_equals
(inh2
.len
, 7);
412 check_equals
(proto
.len
, undefined);
414 inh2
.ogs
= 5; // overridden getter-setter
415 var inh2d
= new Object;
416 check
(proto
.addProperty
("ogs", getLen
, setLen
));
417 inh2d
.__proto__
= inh2
;
422 // Inheritance is: inh2d : inh2 : proto
423 // inh2d.ogs doesn't exist at this time
424 // inh2.ogs is a normal member (value: 5)
425 // proto.ogs is a getter-setter (changes: this._len)
427 check
( ! inh2d
.hasOwnProperty
("ogs") );
428 check
( inh2d
.__proto__
.hasOwnProperty
("ogs") );
429 check
( inh2d
.__proto__
.__proto__
.hasOwnProperty
("ogs") );
430 check_equals
(inh2d
.ogs
, 5); // find inh2.ogs
431 check_equals
(inh2
.ogs
, 5); // find inh2.ogs
432 check_equals
(inh2
.__proto__
.ogs
, 14); // find proto.ogs
433 inh2d
.ogs
= 54; // sets what ?
434 check_equals
(inh2d
._len
, 54); // this._len ! So the getter-setter takes precedence
435 check_equals
(inh2d
.ogs
, 5); // does NOT override inh2.ogs normal member
436 check_equals
(inh2
.ogs
, 5); // find inh2.ogs
437 check_equals
(inh2
.__proto__
.ogs
, 14); // find proto.ogs
439 // Override addProperty member
440 var o
= new Object();
441 o
.addProperty
= function(a
, b
) { return a
+b
; };
442 var c
= o
.addProperty
(2,5);
444 check
(o
.addProperty
!= Object.prototype
.addProperty
);
447 mem_setter
= function(x
)
452 mem_getter
= function()
457 o
.addProperty
('mem', mem_getter
, mem_setter
);
458 check_equals
(typeof(o
.mem
), 'undefined');
459 o
.mem
= 3; // watch out for recursion !
460 check_equals
(o
.mem
, 3);
461 check_equals
(o
.mem2
, 3);
463 // Test double-recursion of setter:
464 // setter1 triggers setter2
466 mem1_getter
= function() { return this.mem1
; };
467 mem1_setter
= function(x
)
469 if ( this.setterCalls
> 2 )
478 mem2_getter
= function() { return this.mem2
; };
479 mem2_setter
= function(x
)
481 if ( this.setterCalls
> 2 )
490 o1
= {}; o1
.addProperty
('mem1', mem1_getter
, mem1_setter
);
491 o2
= {}; o2
.addProperty
('mem2', mem2_getter
, mem2_setter
);
493 o1
.setterCalls
= o2
.setterCalls
= 0; // reset counters
495 #if OUTPUT_VERSION
== 6
496 check_equals
(o1
.setterCalls
, 1);
497 check_equals
(o2
.setterCalls
, 1);
499 // SWF7+ doesn't protect recursion..
500 xcheck_equals
(o1
.setterCalls
, 3);
501 xcheck_equals
(o2
.setterCalls
, 3);
503 check_equals
(o1
.mem1
, 3);
504 check_equals
(o1
.mem1
, 3);
506 o1
.setterCalls
= o2
.setterCalls
= 0; // reset counters
508 #if OUTPUT_VERSION
== 6
509 check_equals
(o1
.setterCalls
, 1);
510 check_equals
(o2
.setterCalls
, 1);
512 // SWF7+ doesn't protect recursion..
513 xcheck_equals
(o1
.setterCalls
, 3);
514 xcheck_equals
(o2
.setterCalls
, 3);
516 check_equals
(o1
.mem1
, 6);
517 check_equals
(o2
.mem2
, 6);
519 // Test having a getter but not a setter
520 getter
= function() { _root
.getcalls
++; return this[_root
.retwhat
]; };
522 r
= o
.addProperty
('lmissing', getter
);
524 r
= o
.addProperty
('lundef', getter
, undefined);
526 r
= o
.addProperty
('lnull', getter
, o
); // self as setter..
528 r
= o
.addProperty
('lnull', getter
, null);
532 check_equals
(getcalls
, 1);
534 _root
.retwhat
='lnull';
535 check_equals
(o
.lnull
, 5);
537 // Test having a setter but not a getter (invalid)
538 setter
= function() { _root
.setcalls
++; };
540 r
= o
.addProperty
('lmissing', undefined, setter
);
542 r
= o
.addProperty
('lundef', null, setter
);
545 // not-setting setter
546 noset_setter
= function(v
) { noset_setter_calls
++; }; // doesn't set cache
547 simple_test_getter
= function() { return this.test
; };
549 o
.addProperty
("test", simple_test_getter
, noset_setter
);
550 noset_setter_calls
=0;
552 check_equals
(noset_setter_calls
, 1);
554 check_equals
(v
, 2); // did still set the cache
556 check_equals
(noset_setter_calls
, 2);
560 // test setter visibility of value (multiplies * 2)
561 timetwo_test_setter
= function(v
) {
562 // note("timetwo_test_setter sees this.test as "+this.test);
567 o
.addProperty
("test", simple_test_getter
, timetwo_test_setter
);
576 /// more sane getter setter test
581 function obj8_getter
() {
585 function obj8_setter
(v
) {
589 obj8
.addProperty
("obj8_prop", obj8_getter
, obj8_setter
);
592 check_equals
(obj8_getter_cnt
, 1);
593 check_equals
(obj8_setter_cnt
, 1);
598 function obj9_getter
() {
600 return this.obj9_prop_cache
;
602 function obj9_setter
(v
) {
604 this.obj9_prop_cache
= v
;
606 obj9
.addProperty
("obj9_prop", obj9_getter
, obj9_setter
);
608 check_equals
(obj9_getter_cnt
, 0);
609 check_equals
(obj9_setter_cnt
, 1);
610 check_equals
(obj9
.obj9_prop
, 10);
611 check_equals
(obj9_getter_cnt
, 1);
612 check_equals
(obj9_setter_cnt
, 1);
614 // Object.addProperty wasn't in SWF5
615 #endif
// OUTPUT_VERSION > 5
617 //----------------------------------------------------
618 // Test Object.toString
619 //----------------------------------------------------
621 check_equals
(Object.prototype
.toString
(), '[object Object]');
622 backup
= Object.prototype
.toString
;
623 Object.prototype
.toString
= function() { return new Object; };
624 check_equals
(typeof(Object.prototype
.toString
()), 'object');
625 Object.prototype
.toString
= function() { return new Number; };
626 check_equals
(Object.prototype
.toString
(), 0);
627 Object.prototype
.toString
= backup
;
629 /// This will ruin later tests while it fails hasOwnProperty.
630 //xcheck_equals(Object.prototype.toLocaleString(), '[object Object]');
631 //backup = Object.prototype.toLocaleString;
632 //Object.prototype.toLocaleString = function() { return new Object; };
633 //xcheck_equals(typeof(Object.prototype.toLocaleString()), 'object');
634 //Object.prototype.toLocaleString = function() { return new Number; };
635 //xcheck_equals(Object.prototype.toLocaleString(), 0);
636 //Object.prototype.toLocaleString = NULL;
638 // Check toLocaleString calls toString
639 backup
= Object.prototype
.toString
;
640 Object.prototype
.toString
= function() { return "toString"+arguments.length
; };
641 check_equals
(Object.prototype
.toLocaleString
(1), "toString0");
642 Object.prototype
.toString
= backup
;
644 //----------------------
646 //----------------------
648 function enumerate
(obj
, enum
)
658 var l0
= new Object({a
:1, b
:2});
659 var l1
= new Object({c
:3, d
:4});
661 var l2
= new Object({e
:5, f
:6});
665 var enum
= new Object;
666 var enumlen
= enumerate
(l2
, enum
);
667 #if OUTPUT_VERSION
> 5
668 check_equals
( enumlen
, 6);
670 check_equals
( enum
["a"], 1);
671 check_equals
( enum
["b"], 2);
672 check_equals
( enum
["c"], 3);
673 check_equals
( enum
["d"], 4);
674 check_equals
( enum
["e"], 5);
675 check_equals
( enum
["f"], 6);
677 // Hide a property of a base object
678 var ret
= ASSetPropFlags
(l0
, "a", 1);
680 var enum
= new Object;
681 var enumlen
= enumerate
(l2
, enum
);
682 #if OUTPUT_VERSION
> 5
683 check_equals
( enumlen
, 5);
686 check_equals
( enum
["a"], undefined);
688 var obj5
= new Object();
690 check_equals
(obj5
['a'], 1);
691 #if OUTPUT_VERSION
< 7
692 check_equals
(obj5
['A'], 1);
694 check_equals
(obj5
['A'], undefined);
697 //----------------------------------------------------
698 // Test Object.isPropertyEnumerable (SWF6 up)
699 //----------------------------------------------------
701 #if OUTPUT_VERSION
> 5
703 // quick built-ins check
704 check
( Object.prototype
.hasOwnProperty
("isPropertyEnumerable") );
705 check
( ! Object.prototype
.isPropertyEnumerable
("isPropertyEnumerable") );
706 check
( Object.prototype
.hasOwnProperty
("addProperty") );
707 check
( ! Object.prototype
.isPropertyEnumerable
("addProperty") );
708 check
( Object.prototype
.hasOwnProperty
("hasOwnProperty") );
709 check
( ! Object.prototype
.isPropertyEnumerable
("hasOwnProperty") );
712 obj6
.member
= "a member";
714 ret
= obj6
.isPropertyEnumerable
('unexistent');
715 check_equals
(typeof(ret
), 'boolean');
716 check
( ! ret
); // non-existant
718 ret
= obj6
.isPropertyEnumerable
('member');
719 check_equals
(typeof(ret
), 'boolean');
722 function enumerableThings
()
724 this.member1
= "a string";
726 ASSetPropFlags
(this, "member2", 1); // hide member2
728 enumerableThings
.prototype
.member3
= new Object;
730 ret
= enumerableThing
.isPropertyEnumerable
('member1');
731 check_equals
( typeof(ret
), 'undefined' );
733 obj7
= new enumerableThings
();
734 check
( obj7
.isPropertyEnumerable
('member1') );
735 check
( ! obj7
.isPropertyEnumerable
('member2') );
736 check_equals
( typeof(obj7
.member3
), 'object' );
737 check
( ! obj7
.isPropertyEnumerable
('member3') );
739 #endif
// OUTPUT_VERSION > 5
741 //----------------------------------------------------
742 // Test Object.isPrototypeOf (SWF6 up)
743 //----------------------------------------------------
745 #if OUTPUT_VERSION
> 5
747 obj8
= function() {};
748 obj9
= function() {};
749 obj9
.__proto__
= new obj8
;
752 check_equals
( typeof(obj8
.isPrototypeOf
(obj8
)), 'boolean' );
753 check_equals
( typeof(obj8
.isPrototypeOf
(undefined)), 'boolean' );
754 check
( obj9
.prototype
.isPrototypeOf
(obj10
) );
755 check
( ! obj8
.prototype
.isPrototypeOf
(obj10
) );
756 check
( obj8
.prototype
.isPrototypeOf
(obj9
) );
757 // TODO: add tests here !
759 #endif
// OUTPUT_VERSION > 5
761 //----------------------------------------------------
762 // Test Object.watch (SWF6 up)
763 //----------------------------------------------------
765 #if OUTPUT_VERSION
> 5
768 simplewatch
= function(nam
, ov
, nv
, d
) {
769 _root
.info
= { nam
:nam
, ov
:ov
, nv
:nv
, d
:d
, tv
:this };
772 r
= o
.watch
('l', simplewatch
, 'cust');
773 check
(r
); // can watch unexisting prop
776 check_equals
(o
.l
, 2); // returned by watcher
777 check_equals
(_root
.info
.nam
, 'l');
778 check_equals
(typeof(_root
.info
.ov
), 'undefined');
779 check_equals
(_root
.info
.nv
, 5);
780 check_equals
(_root
.info
.d
, 'cust');
781 check_equals
(_root
.info
.tv
, o
);
785 check
(!o
.unwatch
('p')); // can not unwatch not-watched props
786 check
(!o
.unwatch
('r')); // can not unwatch non-watched props
787 check
(o
.unwatch
('l')); // can unwatch non-existing but watched vars
789 // watch a getter-setter
791 get_l
= function() { _root
.get_l_calls
++; return this.l
; };
792 set_l
= function(v
) { _root
.set_l_calls
++; this.l
=v
; };
793 r
= o
.watch
('l', simplewatch
, 'cust2');
795 check_equals
(typeof(_root
.info
), 'undefined'); // just checking...
796 _root
.ret
= 'return from watch';
797 _root
.get_l_calls
=_root
.set_l_calls
=0;
798 r
= o
.addProperty
("l", get_l
, set_l
);
800 check_equals
(_root
.info
.nam
, 'l'); // gnash fails calling the watch trigger at all here
801 check_equals
(typeof(_root
.info
.ov
), 'undefined');
802 check_equals
(typeof(_root
.info
.nv
), 'undefined'); // underlying value of getter-setter was undefined
803 check_equals
(_root
.info
.d
, 'cust2');
804 check_equals
(_root
.info
.tv
, o
);
805 check_equals
(_root
.get_l_calls
, 0);
806 check_equals
(_root
.set_l_calls
, 0);
808 // if a property did exist already when adding a getter-setter, it's watcher
811 _root
.get_l_calls
=_root
.set_l_calls
=0;
812 r
= o
.addProperty
("l", get_l
, set_l
);
814 check_equals
(typeof(_root
.info
), 'undefined');
815 check_equals
(_root
.get_l_calls
, 0);
816 check_equals
(_root
.set_l_calls
, 0);
818 check_equals
(r
, 'return from watch');
820 // Getter/setter is not invoked, but watcher was used to set it's
821 // underlying value, check this:
823 check_equals
(v
, 'return from watch');
826 _root
.get_l_calls
=_root
.set_l_calls
=0;
828 o
.l
= 'ciao'; // watched, and invokes setter
829 #if OUTPUT_VERSION
< 7
830 check_equals
(_root
.info
.ov
, 'return from watch'); // old value
831 xcheck_equals
(_root
.info
.nv
, 'ciao'); // we requested this
832 check_equals
(_root
.info
.d
, 'cust2');
833 check_equals
(_root
.info
.tv
, o
);
834 check_equals
(_root
.get_l_calls
, 0); // should get underlying value, not invoke getter
835 check_equals
(_root
.set_l_calls
, 1);
837 check_equals
(_root
.info
.ov
, 'return from watch'); // old value
838 check_equals
(_root
.info
.nv
, 'return from watch'); // mmm ?
839 check_equals
(_root
.info
.d
, 'cust2');
840 check_equals
(_root
.info
.tv
, o
);
841 check_equals
(_root
.get_l_calls
, 0); // should get underlying value, not invoke getter
842 xcheck_equals
(_root
.set_l_calls
, 65);
846 check
(!r
); // can't unwatch while the property is a getter-setter
849 check
(r
); // now we can unwatch.. (gnash fails as it removed the watch before)
851 // TODO: watch a getter-setter in the inheritance chain
853 //o2 = {}; o2.__proto__ = o;
856 #endif
// OUTPUT_VERSION > 5
858 //----------------------------------------------------
859 // Test Object.unwatch (SWF6 up)
860 //----------------------------------------------------
862 #if OUTPUT_VERSION
> 5
864 // TODO: add tests here !
866 #endif
// OUTPUT_VERSION > 5
869 nothing
= new Object ();
870 nothing
.toString
= function() { return "toString"; };
872 check_equals
("string + " + nothing
, "string + toString");
873 nothing
.__proto__
= undefined;
874 #if OUTPUT_VERSION
< 7
875 check_equals
("string + " + nothing
, "string + ");
877 check_equals
("string + " + nothing
, "string + undefined");
880 nothing2
= new Object();
881 nothing2
.__proto__
= undefined;
882 #if OUTPUT_VERSION
< 7
883 check_equals
("string + " + nothing2
, "string + ");
885 check_equals
("string + " + nothing
, "string + undefined");
888 nothing2
.valueOf
= function() { return "valueOf"; };
889 check_equals
("string + " + nothing2
, "string + valueOf");
891 /// Test __resolve property
894 check_equals
(o
.a
, undefined);
895 check_equals
(o
.b
, undefined);
901 o
.__resolve
= function(arg
) {
907 check_equals
(o
.a
, "passed");
908 check_equals
(typeof(result
), "string");
909 check_equals
(resolveCalled
, 1);
910 check_equals
(result
, "a");
912 check_equals
(o
.b
, "passed");
913 check_equals
(typeof(result
), "string");
914 check_equals
(resolveCalled
, 2);
915 check_equals
(result
, "b");
917 check_equals
(o
.quibbleDibblePropertyWithASillyName
, "passed");
918 check_equals
(typeof(result
), "string");
919 check_equals
(resolveCalled
, 3);
920 check_equals
(result
, "quibbleDibblePropertyWithASillyName");
926 check_equals
(typeof(result
), "undefined");
927 check_equals
(resolveCalled
, 3);
931 check_equals
(typeof(result
), "string");
932 check_equals
(result
, "udef");
933 check_equals
(resolveCalled
, 4);
935 check_equals
(g
.cips
, "passed");
936 check_equals
(result
, "cips");
937 check_equals
(resolveCalled
, 5);
939 /// Check __proto__ and prototype during construction
941 TestO
= function() {};
942 TestO
.prototype
= {};
943 TestO
.prototype
.toString
= function() { return "hello there"; };
945 // Set to invisible in all versions up to 9.
946 ASSetPropFlags
(TestO
, null, 8193);
947 check_equals
(TestO
.prototype
, undefined);
951 /// prototype became __proto__
952 check_equals
(typeof(o
.__proto__
), "object");
953 check_equals
(o
.toString
(), "hello there");
955 /// prototye is still invisible
956 check_equals
(TestO
.prototype
, undefined);
958 /// Check DisplayObject property lookup.
960 /// Apparently no DisplayObjects are included in the prototype
964 nonk
.__proto__
= _root
;
965 _root
.bobo
= "hi there";
966 _root
.__proto__
.ubble
= "U!";
972 check
(nonk
.__proto__
._width
);
973 check_equals
(nonk
.__proto__
.bobo
, "hi there");
974 check
(nonk
.__proto__
);
976 _root
.createTextField
("tf", getNextHighestDepth
(), 0, 0, 10, 10);
977 nonk
.__proto__
= _root
.tf
;
978 check
(nonk
.__proto__
);
980 check
(nonk
.__proto__
._width
);
982 // Check that running Object's constructor doesn't change __proto__.
983 // This was only because we were doing something stupid before.
986 check_equals
(this.__proto__
.toString
(), "orig");
988 check_equals
(this.__proto__
.toString
(), "orig");
993 I
.prototype
.toString
= function() { return "orig"; };
997 ////////////////////////////////
999 // Messing about here with global classes may ruin later tests, so don't add
1009 check_equals
(typeof(o
), "undefined");
1011 check_equals
(typeof(o
), "object");
1012 check_equals
(o
.toString
(), "7");
1014 check_equals
(typeof(o
), "object");
1015 check_equals
(o
.toString
(), "true");
1019 check_equals
(typeof(o
), "undefined");
1021 check_equals
(typeof(o
), "object");
1022 check_equals
(o
.toString
(), "true");
1026 check_equals
(typeof(o
), "undefined");
1028 #if OUTPUT_VERSION
<= 5
1032 #if OUTPUT_VERSION
>= 6