1+ import TKUnit = require( "./TKUnit" ) ;
2+ import observable = require( "data/observable" ) ;
3+ import weakEvents = require( "ui/core/weak-event-listener" ) ;
4+ import helper = require( "./ui/helper" ) ;
5+
6+ class Target {
7+ public counter : number = 0 ;
8+ public onEvent ( data : observable . EventData ) {
9+ this . counter ++ ;
10+ }
11+
12+ }
13+
14+ export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_source ( ) {
15+ TKUnit . assertThrows ( ( ) => {
16+ weakEvents . addWeakEventListener ( undefined , "eventName" , emptyHandler , { } ) ;
17+ } ) ;
18+ }
19+
20+ export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_target ( ) {
21+ TKUnit . assertThrows ( ( ) => {
22+ weakEvents . addWeakEventListener ( new observable . Observable ( ) , "eventName" , emptyHandler , undefined ) ;
23+ } ) ;
24+ }
25+
26+ export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_handler ( ) {
27+ TKUnit . assertThrows ( ( ) => {
28+ weakEvents . addWeakEventListener ( new observable . Observable ( ) , "eventName" , undefined , { } ) ;
29+ } ) ;
30+ }
31+
32+ export function test_addWeakEventListener_throwsWhenCalledwitnInvalid_name ( ) {
33+ TKUnit . assertThrows ( ( ) => {
34+ weakEvents . addWeakEventListener ( new observable . Observable ( ) , undefined , emptyHandler , { } ) ;
35+ } ) ;
36+ }
37+
38+ export function test_addWeakEventListener_listensForEvent ( ) {
39+ var source = new observable . Observable ( ) ;
40+ var target = new Target ( ) ;
41+
42+ weakEvents . addWeakEventListener (
43+ source ,
44+ observable . Observable . propertyChangeEvent ,
45+ target . onEvent ,
46+ target ) ;
47+
48+ helper . forceGC ( ) ;
49+
50+ source . set ( "testProp" , "some value" ) ;
51+
52+ TKUnit . assertEqual ( target . counter , 1 , "Handler not called." ) ;
53+ }
54+
55+ export function test_addWeakEventListener_listensForEven_multipleTargetst ( ) {
56+ var source = new observable . Observable ( ) ;
57+ var target1 = new Target ( ) ;
58+ var target2 = new Target ( ) ;
59+
60+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target1 . onEvent , target1 ) ;
61+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target2 . onEvent , target2 ) ;
62+
63+ helper . forceGC ( ) ;
64+
65+ source . set ( "testProp" , "some value" ) ;
66+
67+ TKUnit . assertEqual ( target1 . counter , 1 , "Handler not called." ) ;
68+ TKUnit . assertEqual ( target2 . counter , 1 , "Handler not called." ) ;
69+ }
70+
71+ export function test_removeWeakEventListener_StopsListeningForEvet ( ) {
72+ var source = new observable . Observable ( ) ;
73+ var target = new Target ( ) ;
74+
75+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target ) ;
76+ weakEvents . removeWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target )
77+
78+ source . set ( "testProp" , "some value" ) ;
79+ TKUnit . assertEqual ( target . counter , 0 , "Handler should not be called." ) ;
80+ }
81+
82+ export function test_handlerIsCalled_WithTargetAsThis ( ) {
83+ var source = new observable . Observable ( ) ;
84+ var target = new Object ( ) ;
85+ var callbackCalled = false ;
86+ var handler = function ( args : observable . EventData ) {
87+ TKUnit . assertEqual ( this , target , "this should be the target" ) ;
88+ callbackCalled = true ;
89+ }
90+
91+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , handler , target ) ;
92+
93+ source . set ( "testProp" , "some value" ) ;
94+ TKUnit . assert ( callbackCalled , "Handler not called." ) ;
95+ }
96+
97+ export function test_listnerDoesNotRetainTarget ( ) {
98+ var source = new observable . Observable ( ) ;
99+ var target = new Target ( ) ;
100+
101+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target ) ;
102+
103+ var targetRef = new WeakRef ( target ) ;
104+ target = undefined ;
105+ helper . forceGC ( ) ;
106+
107+ TKUnit . assert ( ! targetRef . get ( ) , "Target should be released after GC" ) ;
108+ }
109+
110+ export function test_listnerDoesNotRetainSource ( ) {
111+ var source = new observable . Observable ( ) ;
112+ var target = new Target ( ) ;
113+
114+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target ) ;
115+
116+ var sourceRef = new WeakRef ( source ) ;
117+ source = undefined ;
118+ helper . forceGC ( ) ;
119+
120+ TKUnit . assert ( ! sourceRef . get ( ) , "Source should be released after GC" ) ;
121+ }
122+
123+ export function test_handlerIsDetached_WhenAllListenersAreRemoved ( ) {
124+ var source = new observable . Observable ( ) ;
125+
126+ var target1 = new Target ( ) ;
127+ var target2 = new Target ( ) ;
128+
129+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target1 . onEvent , target1 ) ;
130+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target2 . onEvent , target2 ) ;
131+
132+ weakEvents . removeWeakEventListener ( source , observable . Observable . propertyChangeEvent , target1 . onEvent , target1 )
133+ weakEvents . removeWeakEventListener ( source , observable . Observable . propertyChangeEvent , target2 . onEvent , target2 )
134+
135+ TKUnit . assert ( ! source . hasListeners ( observable . Observable . propertyChangeEvent ) , "All events should be detached" ) ;
136+ }
137+
138+ export function test_autoDetachingOfDeadReferences ( ) {
139+ var source = new observable . Observable ( ) ;
140+
141+ for ( var i = 0 ; i < 100 ; i ++ ) {
142+ addListenerWithSource ( source ) ;
143+ }
144+
145+ helper . forceGC ( ) ;
146+
147+ var target = new Target ( ) ;
148+
149+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target ) ;
150+ weakEvents . removeWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target )
151+
152+ TKUnit . assert ( ! source . hasListeners ( observable . Observable . propertyChangeEvent ) , "All events should be detached" ) ;
153+ }
154+
155+ function addListenerWithSource ( source : observable . Observable ) {
156+ var target = new Target ( ) ;
157+ weakEvents . addWeakEventListener ( source , observable . Observable . propertyChangeEvent , target . onEvent , target )
158+ }
159+
160+ function emptyHandler ( data : observable . EventData ) {
161+ // Do nothing.
162+ }
0 commit comments