@@ -36,13 +36,14 @@ describe("makeCancelable", () => {
3636 await expectAbort ( cancelable ) ;
3737 } ) ;
3838
39- it ( "should return an object with a promise, cancel function, and isCancelled function" , ( ) => {
39+ it ( "should return an object with a promise, cancel function, isCancelled function, and signal " , ( ) => {
4040 const promise = wait ( 25 ) ;
4141 const cancelable = makeCancelable ( promise ) ;
4242 expect ( cancelable ) . to . be . an ( "object" ) ;
4343 expect ( cancelable . promise ) . to . be . a ( "promise" ) ;
4444 expect ( cancelable . cancel ) . to . be . a ( "function" ) ;
4545 expect ( cancelable . isCancelled ) . to . be . a ( "function" ) ;
46+ expect ( cancelable . signal ) . to . be . an ( "AbortSignal" ) ;
4647 } ) ;
4748
4849 it ( "should resolve the promise if not cancelled" , async ( ) => {
@@ -138,4 +139,91 @@ describe("makeCancelable", () => {
138139 }
139140 }
140141 } ) ;
142+
143+ describe ( "signal property" , ( ) => {
144+ it ( "should be an AbortSignal instance" , ( ) => {
145+ const promise = wait ( 25 ) ;
146+ const cancelable = makeCancelable ( promise ) ;
147+ expect ( cancelable . signal ) . to . be . instanceOf ( AbortSignal ) ;
148+ } ) ;
149+
150+ it ( "should reflect cancellation state" , ( ) => {
151+ const promise = wait ( 25 ) ;
152+ const cancelable = makeCancelable ( promise ) ;
153+ expect ( cancelable . signal . aborted ) . to . be . false ;
154+ cancelable . cancel ( ) ;
155+ expect ( cancelable . signal . aborted ) . to . be . true ;
156+ } ) ;
157+
158+ it ( "should be usable with fetch" , async ( ) => {
159+ const promise = wait ( 25 ) ;
160+ const cancelable = makeCancelable ( promise ) ;
161+
162+ // Simulate a fetch request that would use the signal
163+ const fetchPromise = new Promise ( ( resolve , reject ) => {
164+ cancelable . signal . addEventListener ( "abort" , ( ) => {
165+ reject ( new AbortPromiseError ( ) ) ;
166+ } ) ;
167+ setTimeout ( resolve , 50 ) ;
168+ } ) ;
169+
170+ cancelable . cancel ( ) ;
171+ try {
172+ await fetchPromise ;
173+ throw new Error ( "Promise should have been rejected" ) ;
174+ } catch ( error : unknown ) {
175+ expect ( error ) . to . be . instanceOf ( AbortPromiseError ) ;
176+ }
177+ } ) ;
178+
179+ it ( "should be usable with multiple promises" , async ( ) => {
180+ const promise1 = wait ( 25 ) ;
181+ const cancelable1 = makeCancelable ( promise1 ) ;
182+
183+ // Simulate multiple operations using the same signal
184+ const operation1 = new Promise ( ( resolve , reject ) => {
185+ cancelable1 . signal . addEventListener ( "abort" , ( ) => reject ( new AbortPromiseError ( ) ) ) ;
186+ setTimeout ( resolve , 50 ) ;
187+ } ) ;
188+
189+ const operation2 = new Promise ( ( resolve , reject ) => {
190+ cancelable1 . signal . addEventListener ( "abort" , ( ) => reject ( new AbortPromiseError ( ) ) ) ;
191+ setTimeout ( resolve , 50 ) ;
192+ } ) ;
193+
194+ cancelable1 . cancel ( ) ;
195+
196+ try {
197+ await operation1 ;
198+ throw new Error ( "Promise should have been rejected" ) ;
199+ } catch ( error : unknown ) {
200+ expect ( error ) . to . be . instanceOf ( AbortPromiseError ) ;
201+ }
202+
203+ try {
204+ await operation2 ;
205+ throw new Error ( "Promise should have been rejected" ) ;
206+ } catch ( error : unknown ) {
207+ expect ( error ) . to . be . instanceOf ( AbortPromiseError ) ;
208+ }
209+ } ) ;
210+
211+ it ( "should handle custom abort reason" , async ( ) => {
212+ const promise = wait ( 25 ) ;
213+ const cancelable = makeCancelable ( promise ) ;
214+ const reason = "Custom abort reason" ;
215+
216+ cancelable . cancel ( reason ) ;
217+
218+ try {
219+ await cancelable . promise ;
220+ throw new Error ( "Promise should have been rejected" ) ;
221+ } catch ( error : unknown ) {
222+ expect ( error ) . to . be . instanceOf ( AbortPromiseError ) ;
223+ if ( error instanceof AbortPromiseError ) {
224+ expect ( error . message ) . to . equal ( "Promise was aborted" ) ;
225+ }
226+ }
227+ } ) ;
228+ } ) ;
141229} ) ;
0 commit comments