1717 * under the License.
1818 */
1919
20- import { AbortError , toPromise , getCombinedController } from './abort_utils' ;
20+ import { AbortError , toPromise , getCombinedSignal } from './abort_utils' ;
2121
2222jest . useFakeTimers ( ) ;
2323
@@ -41,7 +41,7 @@ describe('AbortUtils', () => {
4141 describe ( 'rejects' , ( ) => {
4242 test ( 'should not reject if the signal does not abort' , async ( ) => {
4343 const controller = new AbortController ( ) ;
44- const promise = toPromise ( controller . signal ) ;
44+ const promise = toPromise ( controller . signal ) . promise ;
4545 const whenRejected = jest . fn ( ) ;
4646 promise . catch ( whenRejected ) ;
4747 await flushPromises ( ) ;
@@ -50,7 +50,7 @@ describe('AbortUtils', () => {
5050
5151 test ( 'should reject if the signal does abort' , async ( ) => {
5252 const controller = new AbortController ( ) ;
53- const promise = toPromise ( controller . signal ) ;
53+ const promise = toPromise ( controller . signal ) . promise ;
5454 const whenRejected = jest . fn ( ) ;
5555 promise . catch ( whenRejected ) ;
5656 controller . abort ( ) ;
@@ -67,29 +67,29 @@ describe('AbortUtils', () => {
6767
6868 test ( 'calling clean up handler prevents rejects' , async ( ) => {
6969 const controller = new AbortController ( ) ;
70- const promise = toPromise ( controller . signal ) ;
70+ const { promise, cleanup } = toPromise ( controller . signal ) ;
7171 const whenRejected = jest . fn ( ) ;
7272 promise . catch ( whenRejected ) ;
73- promise . cleanup ( ) ;
73+ cleanup ( ) ;
7474 controller . abort ( ) ;
7575 await flushPromises ( ) ;
7676 expect ( whenRejected ) . not . toBeCalled ( ) ;
7777 } ) ;
7878 } ) ;
7979 } ) ;
8080
81- describe ( 'getCombinedController ' , ( ) => {
82- test ( 'should return an AbortController ' , ( ) => {
83- const controller = getCombinedController ( [ ] ) ;
84- expect ( controller ) . toBeInstanceOf ( AbortController ) ;
81+ describe ( 'getCombinedSignal ' , ( ) => {
82+ test ( 'should return an AbortSignal ' , ( ) => {
83+ const signal = getCombinedSignal ( [ ] ) . signal ;
84+ expect ( signal ) . toBeInstanceOf ( AbortSignal ) ;
8585 } ) ;
8686
8787 test ( 'should not abort if none of the signals abort' , async ( ) => {
8888 const controller1 = new AbortController ( ) ;
8989 const controller2 = new AbortController ( ) ;
9090 setTimeout ( ( ) => controller1 . abort ( ) , 2000 ) ;
9191 setTimeout ( ( ) => controller2 . abort ( ) , 1000 ) ;
92- const signal = getCombinedController ( [ controller1 . signal , controller2 . signal ] ) . signal ;
92+ const signal = getCombinedSignal ( [ controller1 . signal , controller2 . signal ] ) . signal ;
9393 expect ( signal . aborted ) . toBe ( false ) ;
9494 jest . advanceTimersByTime ( 500 ) ;
9595 await flushPromises ( ) ;
@@ -101,7 +101,7 @@ describe('AbortUtils', () => {
101101 const controller2 = new AbortController ( ) ;
102102 setTimeout ( ( ) => controller1 . abort ( ) , 2000 ) ;
103103 setTimeout ( ( ) => controller2 . abort ( ) , 1000 ) ;
104- const signal = getCombinedController ( [ controller1 . signal , controller2 . signal ] ) . signal ;
104+ const signal = getCombinedSignal ( [ controller1 . signal , controller2 . signal ] ) . signal ;
105105 expect ( signal . aborted ) . toBe ( false ) ;
106106 jest . advanceTimersByTime ( 1000 ) ;
107107 await flushPromises ( ) ;
@@ -112,8 +112,56 @@ describe('AbortUtils', () => {
112112 const controller1 = new AbortController ( ) ;
113113 const controller2 = new AbortController ( ) ;
114114 controller1 . abort ( ) ;
115- const signal = getCombinedController ( [ controller1 . signal , controller2 . signal ] ) . signal ;
115+ const signal = getCombinedSignal ( [ controller1 . signal , controller2 . signal ] ) . signal ;
116116 expect ( signal . aborted ) . toBe ( true ) ;
117117 } ) ;
118+
119+ describe ( 'cleanup listener' , ( ) => {
120+ const createMockController = ( ) => {
121+ const controller = new AbortController ( ) ;
122+ const spyAddListener = jest . spyOn ( controller . signal , 'addEventListener' ) ;
123+ const spyRemoveListener = jest . spyOn ( controller . signal , 'removeEventListener' ) ;
124+ return {
125+ controller,
126+ getTotalListeners : ( ) =>
127+ Math . max ( spyAddListener . mock . calls . length - spyRemoveListener . mock . calls . length , 0 ) ,
128+ } ;
129+ } ;
130+
131+ test ( 'cleanup should cleanup inner listeners' , ( ) => {
132+ const controller1 = createMockController ( ) ;
133+ const controller2 = createMockController ( ) ;
134+
135+ const { cleanup } = getCombinedSignal ( [
136+ controller1 . controller . signal ,
137+ controller2 . controller . signal ,
138+ ] ) ;
139+
140+ expect ( controller1 . getTotalListeners ( ) ) . toBe ( 1 ) ;
141+ expect ( controller2 . getTotalListeners ( ) ) . toBe ( 1 ) ;
142+
143+ cleanup ( ) ;
144+
145+ expect ( controller1 . getTotalListeners ( ) ) . toBe ( 0 ) ;
146+ expect ( controller2 . getTotalListeners ( ) ) . toBe ( 0 ) ;
147+ } ) ;
148+
149+ test ( 'abort should cleanup inner listeners' , async ( ) => {
150+ const controller1 = createMockController ( ) ;
151+ const controller2 = createMockController ( ) ;
152+
153+ getCombinedSignal ( [ controller1 . controller . signal , controller2 . controller . signal ] ) ;
154+
155+ expect ( controller1 . getTotalListeners ( ) ) . toBe ( 1 ) ;
156+ expect ( controller2 . getTotalListeners ( ) ) . toBe ( 1 ) ;
157+
158+ controller1 . controller . abort ( ) ;
159+
160+ await flushPromises ( ) ;
161+
162+ expect ( controller1 . getTotalListeners ( ) ) . toBe ( 0 ) ;
163+ expect ( controller2 . getTotalListeners ( ) ) . toBe ( 0 ) ;
164+ } ) ;
165+ } ) ;
118166 } ) ;
119167} ) ;
0 commit comments