1namespace ts { 2 const libFile: TestFSWithWatch.File = { 3 path: "/a/lib/lib.d.ts", 4 content: `/// <reference no-default-lib="true"/> 5interface Boolean {} 6interface Function {} 7interface IArguments {} 8interface Number { toExponential: any; } 9interface Object {} 10declare function fetch(input?, init?): Promise<Response>; 11interface Response extends Body { 12 readonly headers: Headers; 13 readonly ok: boolean; 14 readonly redirected: boolean; 15 readonly status: number; 16 readonly statusText: string; 17 readonly trailer: Promise<Headers>; 18 readonly type: ResponseType; 19 readonly url: string; 20 clone(): Response; 21} 22interface Body { 23 readonly body: ReadableStream | null; 24 readonly bodyUsed: boolean; 25 arrayBuffer(): Promise<ArrayBuffer>; 26 blob(): Promise<Blob>; 27 formData(): Promise<FormData>; 28 json(): Promise<any>; 29 text(): Promise<string>; 30} 31declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>; 32interface PromiseLike<T> { 33 /** 34 * Attaches callbacks for the resolution and/or rejection of the Promise. 35 * @param onfulfilled The callback to execute when the Promise is resolved. 36 * @param onrejected The callback to execute when the Promise is rejected. 37 * @returns A Promise for the completion of which ever callback is executed. 38 */ 39 then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>; 40} 41interface Promise<T> { 42 /** 43 * Attaches callbacks for the resolution and/or rejection of the Promise. 44 * @param onfulfilled The callback to execute when the Promise is resolved. 45 * @param onrejected The callback to execute when the Promise is rejected. 46 * @returns A Promise for the completion of which ever callback is executed. 47 */ 48 then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>; 49 50 /** 51 * Attaches a callback for only the rejection of the Promise. 52 * @param onrejected The callback to execute when the Promise is rejected. 53 * @returns A Promise for the completion of the callback. 54 */ 55 catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>; 56} 57interface PromiseConstructor { 58 /** 59 * A reference to the prototype. 60 */ 61 readonly prototype: Promise<any>; 62 63 /** 64 * Creates a new Promise. 65 * @param executor A callback used to initialize the promise. This callback is passed two arguments: 66 * a resolve callback used resolve the promise with a value or the result of another promise, 67 * and a reject callback used to reject the promise with a provided reason or error. 68 */ 69 new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>; 70 71 /** 72 * Creates a Promise that is resolved with an array of results when all of the provided Promises 73 * resolve, or rejected when any Promise is rejected. 74 * @param values An array of Promises. 75 * @returns A new Promise. 76 */ 77 all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; 78 79 /** 80 * Creates a Promise that is resolved with an array of results when all of the provided Promises 81 * resolve, or rejected when any Promise is rejected. 82 * @param values An array of Promises. 83 * @returns A new Promise. 84 */ 85 all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; 86 87 /** 88 * Creates a Promise that is resolved with an array of results when all of the provided Promises 89 * resolve, or rejected when any Promise is rejected. 90 * @param values An array of Promises. 91 * @returns A new Promise. 92 */ 93 all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; 94 95 /** 96 * Creates a Promise that is resolved with an array of results when all of the provided Promises 97 * resolve, or rejected when any Promise is rejected. 98 * @param values An array of Promises. 99 * @returns A new Promise. 100 */ 101 all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; 102 103 /** 104 * Creates a Promise that is resolved with an array of results when all of the provided Promises 105 * resolve, or rejected when any Promise is rejected. 106 * @param values An array of Promises. 107 * @returns A new Promise. 108 */ 109 all<T1, T2, T3, T4, T5, T6>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; 110 111 /** 112 * Creates a Promise that is resolved with an array of results when all of the provided Promises 113 * resolve, or rejected when any Promise is rejected. 114 * @param values An array of Promises. 115 * @returns A new Promise. 116 */ 117 all<T1, T2, T3, T4, T5>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; 118 119 /** 120 * Creates a Promise that is resolved with an array of results when all of the provided Promises 121 * resolve, or rejected when any Promise is rejected. 122 * @param values An array of Promises. 123 * @returns A new Promise. 124 */ 125 all<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>]): Promise<[T1, T2, T3, T4]>; 126 127 /** 128 * Creates a Promise that is resolved with an array of results when all of the provided Promises 129 * resolve, or rejected when any Promise is rejected. 130 * @param values An array of Promises. 131 * @returns A new Promise. 132 */ 133 all<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; 134 135 /** 136 * Creates a Promise that is resolved with an array of results when all of the provided Promises 137 * resolve, or rejected when any Promise is rejected. 138 * @param values An array of Promises. 139 * @returns A new Promise. 140 */ 141 all<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; 142 143 /** 144 * Creates a Promise that is resolved with an array of results when all of the provided Promises 145 * resolve, or rejected when any Promise is rejected. 146 * @param values An array of Promises. 147 * @returns A new Promise. 148 */ 149 all<T>(values: (T | PromiseLike<T>)[]): Promise<T[]>; 150 151 /** 152 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 153 * or rejected. 154 * @param values An array of Promises. 155 * @returns A new Promise. 156 */ 157 race<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9 | T10>; 158 159 /** 160 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 161 * or rejected. 162 * @param values An array of Promises. 163 * @returns A new Promise. 164 */ 165 race<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9>; 166 167 /** 168 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 169 * or rejected. 170 * @param values An array of Promises. 171 * @returns A new Promise. 172 */ 173 race<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8>; 174 175 /** 176 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 177 * or rejected. 178 * @param values An array of Promises. 179 * @returns A new Promise. 180 */ 181 race<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<T1 | T2 | T3 | T4 | T5 | T6 | T7>; 182 183 /** 184 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 185 * or rejected. 186 * @param values An array of Promises. 187 * @returns A new Promise. 188 */ 189 race<T1, T2, T3, T4, T5, T6>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<T1 | T2 | T3 | T4 | T5 | T6>; 190 191 /** 192 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 193 * or rejected. 194 * @param values An array of Promises. 195 * @returns A new Promise. 196 */ 197 race<T1, T2, T3, T4, T5>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<T1 | T2 | T3 | T4 | T5>; 198 199 /** 200 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 201 * or rejected. 202 * @param values An array of Promises. 203 * @returns A new Promise. 204 */ 205 race<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<T1 | T2 | T3 | T4>; 206 207 /** 208 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 209 * or rejected. 210 * @param values An array of Promises. 211 * @returns A new Promise. 212 */ 213 race<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<T1 | T2 | T3>; 214 215 /** 216 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 217 * or rejected. 218 * @param values An array of Promises. 219 * @returns A new Promise. 220 */ 221 race<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<T1 | T2>; 222 223 /** 224 * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved 225 * or rejected. 226 * @param values An array of Promises. 227 * @returns A new Promise. 228 */ 229 race<T>(values: (T | PromiseLike<T>)[]): Promise<T>; 230 231 /** 232 * Creates a new rejected promise for the provided reason. 233 * @param reason The reason the promise was rejected. 234 * @returns A new rejected Promise. 235 */ 236 reject<T = never>(reason?: any): Promise<T>; 237 238 /** 239 * Creates a new resolved promise for the provided value. 240 * @param value A promise. 241 * @returns A promise whose internal state matches the provided promise. 242 */ 243 resolve<T>(value: T | PromiseLike<T>): Promise<T>; 244 245 /** 246 * Creates a new resolved promise . 247 * @returns A resolved promise. 248 */ 249 resolve(): Promise<void>; 250} 251 252declare var Promise: PromiseConstructor; 253interface RegExp {} 254interface String { charAt: any; } 255interface Array<T> {}` 256 }; 257 258 const moduleFile: TestFSWithWatch.File = { 259 path: "/module.ts", 260 content: 261`export function fn(res: any): any { 262 return res; 263}` 264 }; 265 266 type WithSkipAndOnly<T extends any[]> = ((...args: T) => void) & { 267 skip: (...args: T) => void; 268 only: (...args: T) => void; 269 }; 270 271 function createTestWrapper<T extends any[]>(fn: (it: Mocha.PendingTestFunction, ...args: T) => void): WithSkipAndOnly<T> { 272 wrapped.skip = (...args: T) => fn(it.skip, ...args); 273 wrapped.only = (...args: T) => fn(it.only, ...args); 274 return wrapped; 275 function wrapped(...args: T) { 276 return fn(it, ...args); 277 } 278 } 279 280 function testConvertToAsyncFunction(it: Mocha.PendingTestFunction, caption: string, text: string, baselineFolder: string, includeLib?: boolean, includeModule?: boolean, expectFailure = false, onlyProvideAction = false) { 281 const t = extractTest(text); 282 const selectionRange = t.ranges.get("selection")!; 283 if (!selectionRange) { 284 throw new Error(`Test ${caption} does not specify selection range`); 285 } 286 287 const extensions = expectFailure ? [Extension.Ts] : [Extension.Ts, Extension.Js]; 288 289 extensions.forEach(extension => 290 it(`${caption} [${extension}]`, () => runBaseline(extension))); 291 292 function runBaseline(extension: Extension) { 293 const path = "/a" + extension; 294 const languageService = makeLanguageService({ path, content: t.source }, includeLib, includeModule); 295 const program = languageService.getProgram()!; 296 297 if (hasSyntacticDiagnostics(program)) { 298 // Don't bother generating JS baselines for inputs that aren't valid JS. 299 assert.equal(Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); 300 return; 301 } 302 303 const f = { 304 path, 305 content: t.source 306 }; 307 308 const sourceFile = program.getSourceFile(path)!; 309 const context: CodeFixContext = { 310 errorCode: 80006, 311 span: { start: selectionRange.pos, length: selectionRange.end - selectionRange.pos }, 312 sourceFile, 313 program, 314 cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, 315 preferences: emptyOptions, 316 host: notImplementedHost, 317 formatContext: formatting.getFormatContext(testFormatSettings, notImplementedHost) 318 }; 319 320 const diagnostics = languageService.getSuggestionDiagnostics(f.path); 321 const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === Diagnostics.This_may_be_converted_to_an_async_function.message && 322 diagnostic.start === context.span.start && diagnostic.length === context.span.length); 323 if (expectFailure) { 324 assert.isUndefined(diagnostic); 325 } 326 else { 327 assert.exists(diagnostic); 328 } 329 330 const actions = codefix.getFixes(context); 331 const action = find(actions, action => action.description === Diagnostics.Convert_to_async_function.message); 332 if (expectFailure && !onlyProvideAction) { 333 assert.isNotTrue(action && action.changes.length > 0); 334 return; 335 } 336 337 assert.isTrue(action && action.changes.length > 0); 338 339 const data: string[] = []; 340 data.push(`// ==ORIGINAL==`); 341 data.push(text.replace("[#|", "/*[#|*/").replace("|]", "/*|]*/")); 342 const changes = action!.changes; 343 assert.lengthOf(changes, 1); 344 345 data.push(`// ==ASYNC FUNCTION::${action!.description}==`); 346 const newText = textChanges.applyChanges(sourceFile.text, changes[0].textChanges); 347 data.push(newText); 348 349 const diagProgram = makeLanguageService({ path, content: newText }, includeLib, includeModule).getProgram()!; 350 assert.isFalse(hasSyntacticDiagnostics(diagProgram)); 351 Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); 352 } 353 354 function makeLanguageService(file: TestFSWithWatch.File, includeLib?: boolean, includeModule?: boolean) { 355 const files = [file]; 356 if (includeLib) { 357 files.push(libFile); // libFile is expensive to parse repeatedly - only test when required 358 } 359 if (includeModule) { 360 files.push(moduleFile); 361 } 362 const host = projectSystem.createServerHost(files); 363 const projectService = projectSystem.createProjectService(host); 364 projectService.openClientFile(file.path); 365 return first(projectService.inferredProjects).getLanguageService(); 366 } 367 368 function hasSyntacticDiagnostics(program: Program) { 369 const diags = program.getSyntacticDiagnostics(); 370 return length(diags) > 0; 371 } 372 } 373 374 const _testConvertToAsyncFunction = createTestWrapper((it, caption: string, text: string) => { 375 testConvertToAsyncFunction(it, caption, text, "convertToAsyncFunction", /*includeLib*/ true); 376 }); 377 378 const _testConvertToAsyncFunctionFailed = createTestWrapper((it, caption: string, text: string) => { 379 testConvertToAsyncFunction(it, caption, text, "convertToAsyncFunction", /*includeLib*/ true, /*includeModule*/ false, /*expectFailure*/ true); 380 }); 381 382 const _testConvertToAsyncFunctionFailedSuggestion = createTestWrapper((it, caption: string, text: string) => { 383 testConvertToAsyncFunction(it, caption, text, "convertToAsyncFunction", /*includeLib*/ true, /*includeModule*/ false, /*expectFailure*/ true, /*onlyProvideAction*/ true); 384 }); 385 386 const _testConvertToAsyncFunctionWithModule = createTestWrapper((it, caption: string, text: string) => { 387 testConvertToAsyncFunction(it, caption, text, "convertToAsyncFunction", /*includeLib*/ true, /*includeModule*/ true); 388 }); 389 390 describe("unittests:: services:: convertToAsyncFunction", () => { 391 _testConvertToAsyncFunction("convertToAsyncFunction_basic", ` 392function [#|f|](): Promise<void>{ 393 return fetch('https://typescriptlang.org').then(result => { console.log(result) }); 394}`); 395 _testConvertToAsyncFunction("convertToAsyncFunction_arrayBindingPattern", ` 396function [#|f|](): Promise<void>{ 397 return fetch('https://typescriptlang.org').then(([result]) => { console.log(result) }); 398}`); 399 _testConvertToAsyncFunction("convertToAsyncFunction_objectBindingPattern", ` 400function [#|f|](): Promise<void>{ 401 return fetch('https://typescriptlang.org').then(({ result }) => { console.log(result) }); 402}`); 403 _testConvertToAsyncFunction("convertToAsyncFunction_arrayBindingPatternRename", ` 404function [#|f|](): Promise<void>{ 405 const result = getResult(); 406 return fetch('https://typescriptlang.org').then(([result]) => { console.log(result) }); 407}`); 408 _testConvertToAsyncFunction("convertToAsyncFunction_objectBindingPatternRename", ` 409function [#|f|](): Promise<void>{ 410 const result = getResult(); 411 return fetch('https://typescriptlang.org').then(({ result }) => { console.log(result) }); 412}`); 413 _testConvertToAsyncFunction("convertToAsyncFunction_basicNoReturnTypeAnnotation", ` 414function [#|f|]() { 415 return fetch('https://typescriptlang.org').then(result => { console.log(result) }); 416}`); 417 _testConvertToAsyncFunction("convertToAsyncFunction_basicWithComments", ` 418function [#|f|](): Promise<void>{ 419 /* Note - some of these comments are removed during the refactor. This is not ideal. */ 420 421 // a 422 /*b*/ return /*c*/ fetch( /*d*/ 'https://typescriptlang.org' /*e*/).then( /*f*/ result /*g*/ => { /*h*/ console.log(/*i*/ result /*j*/) /*k*/}/*l*/); 423 // m 424}`); 425 426 _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunction", ` 427[#|():Promise<void> => {|] 428 return fetch('https://typescriptlang.org').then(result => console.log(result)); 429}`); 430 _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunctionNoAnnotation", ` 431[#|() => {|] 432 return fetch('https://typescriptlang.org').then(result => console.log(result)); 433}`); 434 _testConvertToAsyncFunction("convertToAsyncFunction_Catch", ` 435function [#|f|]():Promise<void> { 436 return fetch('https://typescriptlang.org').then(result => { console.log(result); }).catch(err => { console.log(err); }); 437}`); 438 _testConvertToAsyncFunction("convertToAsyncFunction_CatchAndRej", ` 439function [#|f|]():Promise<void> { 440 return fetch('https://typescriptlang.org').then(result => { console.log(result); }, rejection => { console.log("rejected:", rejection); }).catch(err => { console.log(err) }); 441}`); 442 _testConvertToAsyncFunction("convertToAsyncFunction_CatchAndRejRef", ` 443function [#|f|]():Promise<void> { 444 return fetch('https://typescriptlang.org').then(res, rej).catch(catch_err) 445} 446function res(result){ 447 console.log(result); 448} 449function rej(rejection){ 450 return rejection.ok; 451} 452function catch_err(err){ 453 console.log(err); 454}`); 455 _testConvertToAsyncFunction("convertToAsyncFunction_CatchRef", ` 456function [#|f|]():Promise<void> { 457 return fetch('https://typescriptlang.org').then(res).catch(catch_err) 458} 459function res(result){ 460 console.log(result); 461} 462function catch_err(err){ 463 console.log(err); 464} 465`); 466 _testConvertToAsyncFunction("convertToAsyncFunction_CatchNoBrackets", ` 467function [#|f|]():Promise<void> { 468 return fetch('https://typescriptlang.org').then(result => console.log(result)).catch(err => console.log(err)); 469}` 470 ); 471 _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs1", ` 472function [#|f|](): Promise<void> { 473 return fetch('https://typescriptlang.org').then( _ => { console.log("done"); }); 474}` 475 ); 476 _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs2", ` 477function [#|f|](): Promise<void> { 478 return fetch('https://typescriptlang.org').then( () => console.log("done") ); 479}` 480 ); 481 _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs3", ` 482function [#|f|](): Promise<void> { 483 return fetch('https://typescriptlang.org').then( () => console.log("almost done") ).then( () => console.log("done") ); 484}` 485 ); 486 _testConvertToAsyncFunction("convertToAsyncFunction_IgnoreArgs4", ` 487function [#|f|]() { 488 return fetch('https://typescriptlang.org').then(res); 489} 490function res(){ 491 console.log("done"); 492}` 493 ); 494 495 _testConvertToAsyncFunction("convertToAsyncFunction_Method", ` 496class Parser { 497 [#|f|]():Promise<void> { 498 return fetch('https://typescriptlang.org').then(result => console.log(result)); 499 } 500}` 501 ); 502 _testConvertToAsyncFunction("convertToAsyncFunction_MultipleCatches", ` 503function [#|f|](): Promise<void> { 504 return fetch('https://typescriptlang.org').then(res => console.log(res)).catch(err => console.log("err", err)).catch(err2 => console.log("err2", err2)); 505}` 506 ); 507 _testConvertToAsyncFunction("convertToAsyncFunction_MultipleThens", ` 508function [#|f|]():Promise<void> { 509 return fetch('https://typescriptlang.org').then(res).then(res2); 510} 511function res(result){ 512 return result.ok; 513} 514function res2(result2){ 515 console.log(result2); 516}` 517 ); 518 _testConvertToAsyncFunction("convertToAsyncFunction_MultipleThensSameVarName", ` 519function [#|f|]():Promise<void> { 520 return fetch('https://typescriptlang.org').then(res).then(res2); 521} 522function res(result){ 523 return result.ok; 524} 525function res2(result){ 526 return result.bodyUsed; 527} 528` 529 ); 530 _testConvertToAsyncFunction("convertToAsyncFunction_NoRes", ` 531function [#|f|]():Promise<void | Response> { 532 return fetch('https://typescriptlang.org').then(null, rejection => console.log("rejected:", rejection)); 533} 534` 535 ); 536 _testConvertToAsyncFunction("convertToAsyncFunction_NoRes2", ` 537function [#|f|]():Promise<void | Response> { 538 return fetch('https://typescriptlang.org').then(undefined).catch(rej => console.log(rej)); 539} 540` 541 ); 542 543 _testConvertToAsyncFunction("convertToAsyncFunction_NoRes3", ` 544function [#|f|]():Promise<void | Response> { 545 return fetch('https://typescriptlang.org').catch(rej => console.log(rej)); 546} 547` 548 ); 549 _testConvertToAsyncFunction("convertToAsyncFunction_NoRes4", ` 550function [#|f|]() { 551 return fetch('https://typescriptlang.org').then(undefined, rejection => console.log("rejected:", rejection)); 552} 553` 554 ); 555 _testConvertToAsyncFunction("convertToAsyncFunction_NoCatchHandler", ` 556function [#|f|]() { 557 return fetch('https://typescriptlang.org').then(x => x.statusText).catch(undefined); 558} 559` 560 ); 561 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestion", ` 562function [#|f|]():Promise<Response> { 563 return fetch('https://typescriptlang.org'); 564} 565` 566 ); 567 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseDotAll", ` 568function [#|f|]():Promise<void>{ 569 return Promise.all([fetch('https://typescriptlang.org'), fetch('https://microsoft.com'), fetch('https://youtube.com')]).then(function(vals){ 570 vals.forEach(console.log); 571 }); 572} 573` 574 ); 575 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionNoPromise", ` 576function [#|f|]():void{ 577} 578` 579 ); 580 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Rej", ` 581function [#|f|]():Promise<void> { 582 return fetch('https://typescriptlang.org').then(result => { console.log(result); }, rejection => { console.log("rejected:", rejection); }); 583} 584` 585 ); 586 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_RejRef", ` 587function [#|f|]():Promise<void> { 588 return fetch('https://typescriptlang.org').then(res, rej); 589} 590function res(result){ 591 console.log(result); 592} 593function rej(err){ 594 console.log(err); 595} 596` 597 ); 598 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_RejNoBrackets", ` 599function [#|f|]():Promise<void> { 600 return fetch('https://typescriptlang.org').then(result => console.log(result), rejection => console.log("rejected:", rejection)); 601} 602` 603 ); 604 605 _testConvertToAsyncFunction("convertToAsyncFunction_ResRef", ` 606function [#|f|]():Promise<boolean> { 607 return fetch('https://typescriptlang.org').then(res); 608} 609function res(result){ 610 return result.ok; 611} 612` 613 ); 614 615 _testConvertToAsyncFunction("convertToAsyncFunction_ResRef1", ` 616class Foo { 617 public [#|method|](): Promise<boolean> { 618 return fetch('a').then(this.foo); 619 } 620 621 private foo(res) { 622 return res.ok; 623 } 624} 625 `); 626 627 _testConvertToAsyncFunction("convertToAsyncFunction_ResRef2", ` 628class Foo { 629 public [#|method|](): Promise<Response> { 630 return fetch('a').then(this.foo); 631 } 632 633 private foo = res => res; 634} 635 `); 636 637 _testConvertToAsyncFunction("convertToAsyncFunction_ResRef3", ` 638const res = (result) => { 639 return result.ok; 640} 641function [#|f|](): Promise<boolean> { 642 return fetch('https://typescriptlang.org').then(res); 643} 644 ` 645 ); 646 647 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef1", ` 648const res = 1; 649function [#|f|]() { 650 return fetch('https://typescriptlang.org').then(res); 651} 652` 653 ); 654 655 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef2", ` 656class Foo { 657 private foo = 1; 658 public [#|method|](): Promise<boolean> { 659 return fetch('a').then(this.foo); 660 } 661} 662` 663 ); 664 665 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef3", ` 666const res = undefined; 667function [#|f|]() { 668 return fetch('https://typescriptlang.org').then(res); 669} 670` 671 ); 672 673 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NoSuggestionResRef4", ` 674class Foo { 675 private foo = undefined; 676 public [#|method|](): Promise<boolean> { 677 return fetch('a').then(this.foo); 678 } 679} 680` 681 ); 682 683 _testConvertToAsyncFunction("convertToAsyncFunction_ResRefNoReturnVal", ` 684function [#|f|]():Promise<void> { 685 return fetch('https://typescriptlang.org').then(res); 686} 687function res(result){ 688 console.log(result); 689} 690` 691 ); 692 693 _testConvertToAsyncFunction("convertToAsyncFunction_ResRefNoReturnVal1", ` 694class Foo { 695 public [#|method|](): Promise<void> { 696 return fetch('a').then(this.foo); 697 } 698 699 private foo(res) { 700 console.log(res); 701 } 702} 703 `); 704 705 _testConvertToAsyncFunction("convertToAsyncFunction_NoBrackets", ` 706function [#|f|]():Promise<void> { 707 return fetch('https://typescriptlang.org').then(result => console.log(result)); 708} 709` 710 ); 711 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally1", ` 712function [#|finallyTest|](): Promise<void> { 713 return fetch("https://typescriptlang.org").then(res => console.log(res)).catch(rej => console.log("error", rej)).finally(console.log("finally!")); 714} 715` 716 ); 717 718 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally2", ` 719function [#|finallyTest|](): Promise<void> { 720 return fetch("https://typescriptlang.org").then(res => console.log(res)).finally(console.log("finally!")); 721} 722` 723 ); 724 725 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Finally3", ` 726function [#|finallyTest|](): Promise<void> { 727 return fetch("https://typescriptlang.org").finally(console.log("finally!")); 728} 729` 730 ); 731 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromise", ` 732function [#|innerPromise|](): Promise<string> { 733 return fetch("https://typescriptlang.org").then(resp => { 734 var blob2 = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 735 return blob2; 736 }).then(blob => { 737 return blob.toString(); 738 }); 739} 740` 741 ); 742 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRet", ` 743function [#|innerPromise|](): Promise<string> { 744 return fetch("https://typescriptlang.org").then(resp => { 745 return resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 746 }).then(blob => { 747 return blob.toString(); 748 }); 749} 750` 751 ); 752 753 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding1", ` 754function [#|innerPromise|](): Promise<string> { 755 return fetch("https://typescriptlang.org").then(resp => { 756 return resp.blob().then(({ blob }) => blob.byteOffset).catch(({ message }) => 'Error ' + message); 757 }).then(blob => { 758 return blob.toString(); 759 }); 760} 761` 762 ); 763 764 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding2", ` 765function [#|innerPromise|](): Promise<string> { 766 return fetch("https://typescriptlang.org").then(resp => { 767 return resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 768 }).then(({ x }) => { 769 return x.toString(); 770 }); 771} 772` 773 ); 774 775 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding3", ` 776function [#|innerPromise|](): Promise<string> { 777 return fetch("https://typescriptlang.org").then(resp => { 778 return resp.blob().then(({ blob }) => blob.byteOffset).catch(({ message }) => 'Error ' + message); 779 }).then(([x, y]) => { 780 return (x || y).toString(); 781 }); 782} 783` 784 ); 785 786 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseRetBinding4", ` 787function [#|innerPromise|](): Promise<string> { 788 return fetch("https://typescriptlang.org").then(resp => { 789 return resp.blob().then(({ blob }: { blob: { byteOffset: number } }) => [0, blob.byteOffset]).catch(({ message }: Error) => ['Error ', message]); 790 }).then(([x, y]) => { 791 return (x || y).toString(); 792 }); 793} 794` 795 ); 796 797 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn01", ` 798function [#|f|]() { 799 let blob = fetch("https://typescriptlang.org").then(resp => console.log(resp)); 800 return blob; 801} 802` 803 ); 804 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn02", ` 805function [#|f|]() { 806 let blob = fetch("https://typescriptlang.org"); 807 blob.then(resp => console.log(resp)); 808 return blob; 809} 810` 811 ); 812 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn03", ` 813function [#|f|]() { 814 let blob = fetch("https://typescriptlang.org") 815 let blob2 = blob.then(resp => console.log(resp)); 816 blob2.catch(err); 817 return blob; 818} 819 820function err (rej) { 821 console.log(rej) 822} 823` 824 ); 825 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn04", ` 826function [#|f|]() { 827 var blob = fetch("https://typescriptlang.org").then(res => console.log(res)), blob2 = fetch("https://microsoft.com").then(res => res.ok).catch(err); 828 return blob; 829} 830function err (rej) { 831 console.log(rej) 832} 833` 834 ); 835 836 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn05", ` 837function [#|f|]() { 838 var blob = fetch("https://typescriptlang.org").then(res => console.log(res)); 839 blob.then(x => x); 840 return blob; 841} 842` 843 ); 844 845 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn06", ` 846function [#|f|]() { 847 var blob = fetch("https://typescriptlang.org"); 848 return blob; 849} 850` 851 ); 852 853 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn07", ` 854function [#|f|]() { 855 let blob = fetch("https://typescriptlang.org"); 856 let blob2 = fetch("https://microsoft.com"); 857 blob2.then(res => console.log("res:", res)); 858 blob.then(resp => console.log(resp)); 859 return blob; 860} 861` 862 ); 863 864 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn08", ` 865function [#|f|]() { 866 let blob = fetch("https://typescriptlang.org"); 867 if (!blob.ok){ 868 return blob; 869 } 870 blob.then(resp => console.log(resp)); 871 return blob; 872} 873` 874 ); 875 876 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn09", ` 877function [#|f|]() { 878 let blob3; 879 let blob = fetch("https://typescriptlang.org"); 880 let blob2 = fetch("https://microsoft.com"); 881 blob2.then(res => console.log("res:", res)); 882 blob.then(resp => console.log(resp)); 883 blob3 = blob2.catch(rej => rej.ok); 884 return blob; 885} 886` 887 ); 888 889 890 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn10", ` 891function [#|f|]() { 892 let blob3; 893 let blob = fetch("https://typescriptlang.org"); 894 let blob2 = fetch("https://microsoft.com"); 895 blob2.then(res => console.log("res:", res)); 896 blob.then(resp => console.log(resp)); 897 blob3 = fetch("test.com"); 898 blob3 = blob2; 899 return blob; 900} 901` 902 ); 903 904 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_VarReturn11", ` 905function [#|f|]() { 906 let blob; 907 return blob; 908} 909` 910 ); 911 912 913 914 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_Param1", ` 915function [#|f|]() { 916 return my_print(fetch("https://typescriptlang.org").then(res => console.log(res))); 917} 918function my_print (resp) { 919 if (resp.ok) { 920 console.log(resp.buffer); 921 } 922 return resp; 923} 924 925` 926 ); 927 928 _testConvertToAsyncFunction("convertToAsyncFunction_Param2", ` 929function [#|f|]() { 930 return my_print(fetch("https://typescriptlang.org").then(res => console.log(res))).catch(err => console.log("Error!", err)); 931} 932function my_print (resp): Promise<void> { 933 if (resp.ok) { 934 console.log(resp.buffer); 935 } 936 return resp; 937} 938 939 940` 941 ); 942 943 _testConvertToAsyncFunction("convertToAsyncFunction_MultipleReturns1", ` 944function [#|f|](): Promise<void> { 945 let x = fetch("https://microsoft.com").then(res => console.log("Microsoft:", res)); 946 if (x.ok) { 947 return fetch("https://typescriptlang.org").then(res => console.log(res)); 948 } 949 return x.then(resp => { 950 var blob = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 951 }); 952} 953` 954 ); 955 956 _testConvertToAsyncFunction("convertToAsyncFunction_MultipleReturns2", ` 957function [#|f|](): Promise<void> { 958 let x = fetch("https://microsoft.com").then(res => console.log("Microsoft:", res)); 959 if (x.ok) { 960 return fetch("https://typescriptlang.org").then(res => console.log(res)); 961 } 962 return x.then(resp => { 963 var blob = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 964 return fetch("https://microsoft.com").then(res => console.log("Another one!")); 965 }); 966} 967` 968 ); 969 970 971 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_SeperateLines", ` 972function [#|f|](): Promise<string> { 973 var blob = fetch("https://typescriptlang.org") 974 blob.then(resp => { 975 var blob = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 976 }); 977 blob.then(blob => { 978 return blob.toString(); 979 }); 980 981 return blob; 982} 983` 984 ); 985 986 987 _testConvertToAsyncFunction("convertToAsyncFunction_InnerVarNameConflict", ` 988function [#|f|](): Promise<string> { 989 return fetch("https://typescriptlang.org").then(resp => { 990 var blob = resp.blob().then(blob => blob.byteOffset).catch(err => 'Error'); 991 }).then(blob => { 992 return blob.toString(); 993 }); 994} 995` 996 ); 997 _testConvertToAsyncFunction("convertToAsyncFunction_InnerPromiseSimple", ` 998function [#|f|](): Promise<string> { 999 return fetch("https://typescriptlang.org").then(resp => { 1000 return resp.blob().then(blob => blob.byteOffset); 1001 }).then(blob => { 1002 return blob.toString(); 1003 }); 1004} 1005` 1006 ); 1007 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen1", ` 1008function [#|f|]() { 1009 return Promise.resolve().then(function () { 1010 return Promise.all([fetch("https://typescriptlang.org"), fetch("https://microsoft.com"), Promise.resolve().then(function () { 1011 return fetch("https://github.com"); 1012 }).then(res => res.toString())]); 1013 }); 1014} 1015` 1016 ); 1017 1018 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen2", ` 1019function [#|f|]() { 1020 return Promise.resolve().then(function () { 1021 return Promise.all([fetch("https://typescriptlang.org"), fetch("https://microsoft.com"), Promise.resolve().then(function () { 1022 return fetch("https://github.com"); 1023 })]).then(res => res.toString()); 1024 }); 1025} 1026` 1027 ); 1028 1029 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen3", ` 1030function [#|f|]() { 1031 return Promise.resolve().then(() => 1032 Promise.all([fetch("https://typescriptlang.org"), fetch("https://microsoft.com"), Promise.resolve().then(function () { 1033 return fetch("https://github.com"); 1034 }).then(res => res.toString())])); 1035} 1036` 1037 ); 1038 1039 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseAllAndThen4", ` 1040function [#|f|]() { 1041 return Promise.resolve().then(() => 1042 Promise.all([fetch("https://typescriptlang.org"), fetch("https://microsoft.com"), Promise.resolve().then(function () { 1043 return fetch("https://github.com"); 1044 })]).then(res => res.toString())); 1045} 1046` 1047 ); 1048 _testConvertToAsyncFunction("convertToAsyncFunction_Scope1", ` 1049function [#|f|]() { 1050 var var1: Response, var2; 1051 return fetch('https://typescriptlang.org').then( _ => 1052 Promise.resolve().then( res => { 1053 var2 = "test"; 1054 return fetch("https://microsoft.com"); 1055 }).then(res => 1056 var1 === res 1057 ) 1058 ).then(res); 1059 } 1060 function res(response){ 1061 console.log(response); 1062 } 1063`); 1064 1065 _testConvertToAsyncFunction("convertToAsyncFunction_Conditionals", ` 1066function [#|f|](){ 1067 return fetch("https://typescriptlang.org").then(res => { 1068 if (res.ok) { 1069 return fetch("https://microsoft.com"); 1070 } 1071 else { 1072 if (res.buffer.length > 5) { 1073 return res; 1074 } 1075 else { 1076 return fetch("https://github.com"); 1077 } 1078 } 1079 }); 1080} 1081` 1082 ); 1083 1084 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThen", ` 1085function [#|f|](){ 1086 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1087} 1088 1089function res(result){ 1090 return result; 1091} 1092 1093function rej(reject){ 1094 return reject; 1095} 1096` 1097 ); 1098 1099 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes01", ` 1100function [#|f|](){ 1101 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1102} 1103 1104function res(result): number { 1105 return 5; 1106} 1107 1108function rej(reject): number { 1109 return 3; 1110} 1111` 1112 ); 1113 1114 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes01NoAnnotations", ` 1115function [#|f|](){ 1116 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1117} 1118 1119function res(result){ 1120 return 5; 1121} 1122 1123function rej(reject){ 1124 return 3; 1125} 1126` 1127 ); 1128 1129 1130 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes02", ` 1131function [#|f|](){ 1132 return fetch("https://typescriptlang.org").then(res => 0).catch(rej => 1).then(res); 1133} 1134 1135function res(result): number { 1136 return 5; 1137} 1138` 1139 ); 1140 1141 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMatchingTypes02NoAnnotations", ` 1142function [#|f|](){ 1143 return fetch("https://typescriptlang.org").then(res => 0).catch(rej => 1).then(res); 1144} 1145 1146function res(result){ 1147 return 5; 1148} 1149` 1150 ); 1151 1152 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes01", ` 1153function [#|f|](){ 1154 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1155} 1156 1157function res(result){ 1158 return 5; 1159} 1160 1161function rej(reject){ 1162 return "Error"; 1163} 1164` 1165 ); 1166 1167 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes02", ` 1168function [#|f|](){ 1169 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1170} 1171 1172function res(result){ 1173 return 5; 1174} 1175 1176function rej(reject): Response{ 1177 return reject; 1178} 1179` 1180 ); 1181 1182 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes02NoAnnotations", ` 1183function [#|f|](){ 1184 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1185} 1186 1187function res(result){ 1188 return 5; 1189} 1190 1191function rej(reject){ 1192 return reject; 1193} 1194` 1195 ); 1196 1197 1198 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes03", ` 1199function [#|f|](){ 1200 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1201} 1202 1203function res(result){ 1204 return 5; 1205} 1206 1207function rej(reject){ 1208 return Promise.resolve(1); 1209} 1210` 1211 ); 1212 1213 _testConvertToAsyncFunction("convertToAsyncFunction_CatchFollowedByThenMismatchTypes04", ` 1214interface a { 1215 name: string; 1216 age: number; 1217} 1218 1219interface b extends a { 1220 color: string; 1221} 1222 1223 1224function [#|f|](){ 1225 return fetch("https://typescriptlang.org").then(res).catch(rej).then(res); 1226} 1227 1228function res(result): b{ 1229 return {name: "myName", age: 22, color: "red"}; 1230} 1231 1232function rej(reject): a{ 1233 return {name: "myName", age: 27}; 1234} 1235` 1236 ); 1237 1238 _testConvertToAsyncFunction("convertToAsyncFunction_ParameterNameCollision", ` 1239async function foo<T>(x: T): Promise<T> { 1240 return x; 1241} 1242 1243function [#|bar|]<T>(x: T): Promise<T> { 1244 return foo(x).then(foo) 1245} 1246` 1247 ); 1248 1249 _testConvertToAsyncFunction("convertToAsyncFunction_Return1", ` 1250function [#|f|](p: Promise<unknown>) { 1251 return p.catch((error: Error) => { 1252 return Promise.reject(error); 1253 }); 1254}` 1255 ); 1256 1257 _testConvertToAsyncFunction("convertToAsyncFunction_Return2", ` 1258function [#|f|](p: Promise<unknown>) { 1259 return p.catch((error: Error) => Promise.reject(error)); 1260}` 1261 ); 1262 1263 _testConvertToAsyncFunction("convertToAsyncFunction_Return3", ` 1264function [#|f|](p: Promise<unknown>) { 1265 return p.catch(function (error: Error) { 1266 return Promise.reject(error); 1267 }); 1268}` 1269 ); 1270 1271 _testConvertToAsyncFunction("convertToAsyncFunction_LocalReturn", ` 1272function [#|f|]() { 1273 let x = fetch("https://typescriptlang.org").then(res => console.log(res)); 1274 return x.catch(err => console.log("Error!", err)); 1275} 1276 1277`); 1278 _testConvertToAsyncFunction("convertToAsyncFunction_PromiseCallInner", ` 1279function [#|f|]() { 1280 return fetch(Promise.resolve(1).then(res => "https://typescriptlang.org")).catch(err => console.log(err)); 1281} 1282 1283`); 1284 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_CatchFollowedByCall", ` 1285function [#|f|](){ 1286 return fetch("https://typescriptlang.org").then(res).catch(rej).toString(); 1287} 1288 1289function res(result){ 1290 return result; 1291} 1292 1293function rej(reject){ 1294 return reject; 1295} 1296` 1297 ); 1298 1299 _testConvertToAsyncFunction("convertToAsyncFunction_Scope2", ` 1300function [#|f|](){ 1301 var i:number; 1302 return fetch("https://typescriptlang.org").then(i => i.ok).then(res => i+1).catch(err => i-1) 1303} 1304` 1305 ); 1306 1307 _testConvertToAsyncFunction("convertToAsyncFunction_Loop", ` 1308function [#|f|](){ 1309 return fetch("https://typescriptlang.org").then(res => { for(let i=0; i<10; i++){ 1310 console.log(res); 1311 }}) 1312} 1313` 1314 ); 1315 1316 _testConvertToAsyncFunction("convertToAsyncFunction_Conditional2", ` 1317function [#|f|](){ 1318 var res = 100; 1319 if (res > 50) { 1320 return fetch("https://typescriptlang.org").then(res => console.log(res)); 1321 } 1322 else { 1323 return fetch("https://typescriptlang.org").then(res_func); 1324 } 1325} 1326 1327function res_func(result){ 1328 console.log(result); 1329} 1330` 1331 ); 1332 1333 _testConvertToAsyncFunction("convertToAsyncFunction_Scope3", ` 1334function [#|f|]() { 1335 var obj; 1336 return fetch("https://typescriptlang.org").then(function (res) { 1337 obj = { 1338 func: function f() { 1339 console.log(res); 1340 } 1341 }; 1342 }); 1343} 1344` 1345 ); 1346 1347 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_NestedFunctionWrongLocation", ` 1348function [#|f|]() { 1349 function fn2(){ 1350 function fn3(){ 1351 return fetch("https://typescriptlang.org").then(res => console.log(res)); 1352 } 1353 return fn3(); 1354 } 1355 return fn2(); 1356} 1357`); 1358 1359 _testConvertToAsyncFunction("convertToAsyncFunction_NestedFunctionRightLocation", ` 1360function f() { 1361 function fn2(){ 1362 function [#|fn3|](){ 1363 return fetch("https://typescriptlang.org").then(res => console.log(res)); 1364 } 1365 return fn3(); 1366 } 1367 return fn2(); 1368} 1369`); 1370 1371 _testConvertToAsyncFunction("convertToAsyncFunction_UntypedFunction", ` 1372function [#|f|]() { 1373 return Promise.resolve().then(res => console.log(res)); 1374} 1375`); 1376 1377 _testConvertToAsyncFunction("convertToAsyncFunction_TernaryConditional", ` 1378function [#|f|]() { 1379 let i; 1380 return Promise.resolve().then(res => res ? i = res : i = 100); 1381} 1382`); 1383 1384 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_ResRejNoArgsArrow", ` 1385 function [#|f|]() { 1386 return Promise.resolve().then(() => 1, () => "a"); 1387 } 1388`); 1389 1390 _testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpression", ` 1391const [#|foo|] = function () { 1392 return fetch('https://typescriptlang.org').then(result => { console.log(result) }); 1393} 1394`); 1395 1396 _testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpressionWithName", ` 1397const foo = function [#|f|]() { 1398 return fetch('https://typescriptlang.org').then(result => { console.log(result) }); 1399} 1400`); 1401 1402 _testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpressionAssignedToBindingPattern", ` 1403const { length } = [#|function|] () { 1404 return fetch('https://typescriptlang.org').then(result => { console.log(result) }); 1405} 1406`); 1407 1408 _testConvertToAsyncFunction("convertToAsyncFunction_catchBlockUniqueParams", ` 1409function [#|f|]() { 1410 return Promise.resolve().then(x => 1).catch(x => "a").then(x => !!x); 1411} 1412`); 1413 1414 _testConvertToAsyncFunction("convertToAsyncFunction_catchBlockUniqueParamsBindingPattern", ` 1415function [#|f|]() { 1416 return Promise.resolve().then(() => ({ x: 3 })).catch(() => ({ x: "a" })).then(({ x }) => !!x); 1417} 1418`); 1419 1420 _testConvertToAsyncFunction("convertToAsyncFunction_bindingPattern", ` 1421function [#|f|]() { 1422 return fetch('https://typescriptlang.org').then(res); 1423} 1424function res({ status, trailer }){ 1425 console.log(status); 1426} 1427`); 1428 1429 _testConvertToAsyncFunction("convertToAsyncFunction_bindingPatternNameCollision", ` 1430function [#|f|]() { 1431 const result = 'https://typescriptlang.org'; 1432 return fetch(result).then(res); 1433} 1434function res({ status, trailer }){ 1435 console.log(status); 1436} 1437`); 1438 1439 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_thenArgumentNotFunction", ` 1440function [#|f|]() { 1441 return Promise.resolve().then(f ? (x => x) : (y => y)); 1442} 1443`); 1444 1445 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_thenArgumentNotFunctionNotLastInChain", ` 1446function [#|f|]() { 1447 return Promise.resolve().then(f ? (x => x) : (y => y)).then(q => q); 1448} 1449`); 1450 1451 _testConvertToAsyncFunction("convertToAsyncFunction_runEffectfulContinuation", ` 1452function [#|f|]() { 1453 return fetch('https://typescriptlang.org').then(res).then(_ => console.log("done")); 1454} 1455function res(result) { 1456 return Promise.resolve().then(x => console.log(result)); 1457} 1458`); 1459 1460 _testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromise", ` 1461function [#|f|]() { 1462 return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText.length)).then(x => console.log(x + 5)); 1463} 1464`); 1465 1466 _testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromiseInBlock", ` 1467function [#|f|]() { 1468 return fetch('https://typescriptlang.org').then(s => { return Promise.resolve(s.statusText.length) }).then(x => x + 5); 1469} 1470`); 1471 1472 _testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsFixablePromise", ` 1473function [#|f|]() { 1474 return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText).then(st => st.length)).then(x => console.log(x + 5)); 1475} 1476`); 1477 1478 _testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsPromiseLastInChain", ` 1479function [#|f|]() { 1480 return fetch('https://typescriptlang.org').then(s => Promise.resolve(s.statusText.length)); 1481} 1482`); 1483 1484 _testConvertToAsyncFunction("convertToAsyncFunction_callbackReturnsRejectedPromiseInTryBlock", ` 1485function [#|f|]() { 1486 return Promise.resolve(1) 1487 .then(x => Promise.reject(x)) 1488 .catch(err => console.log(err)); 1489} 1490`); 1491 1492 _testConvertToAsyncFunction("convertToAsyncFunction_nestedPromises", ` 1493function [#|f|]() { 1494 return fetch('https://typescriptlang.org').then(x => Promise.resolve(3).then(y => Promise.resolve(x.statusText.length + y))); 1495} 1496`); 1497 1498 _testConvertToAsyncFunction("convertToAsyncFunction_noArgs1", ` 1499function delay(millis: number): Promise<void> { 1500 throw "no" 1501} 1502 1503function [#|main2|]() { 1504 console.log("Please wait. Loading."); 1505 return delay(500) 1506 .then(() => { console.log("."); return delay(500); }) 1507 .then(() => { console.log("."); return delay(500); }) 1508 .then(() => { console.log("."); return delay(500); }) 1509} 1510 `); 1511 1512 _testConvertToAsyncFunction("convertToAsyncFunction_noArgs2", ` 1513function delay(millis: number): Promise<void> { 1514 throw "no" 1515} 1516 1517function [#|main2|]() { 1518 console.log("Please wait. Loading."); 1519 return delay(500) 1520 .then(() => delay(500)) 1521 .then(() => delay(500)) 1522 .then(() => delay(500)) 1523} 1524 `); 1525 1526 _testConvertToAsyncFunction("convertToAsyncFunction_exportModifier", ` 1527export function [#|foo|]() { 1528 return fetch('https://typescriptlang.org').then(s => console.log(s)); 1529} 1530`); 1531 1532 _testConvertToAsyncFunction("convertToAsyncFunction_OutermostOnlySuccess", ` 1533function [#|foo|]() { 1534 return fetch('a').then(() => { 1535 return fetch('b').then(() => 'c'); 1536 }) 1537} 1538`); 1539 _testConvertToAsyncFunction("convertToAsyncFunction_decoratedMethod", ` 1540function decorator() { 1541 return (target: any, key: any, descriptor: PropertyDescriptor) => descriptor; 1542} 1543class Foo { 1544 @decorator() 1545 [#|method|]() { 1546 return fetch('a').then(x => x); 1547 } 1548} 1549`); 1550 1551 _testConvertToAsyncFunction("convertToAsyncFunction_decoratedMethodWithSingleLineComment", ` 1552function decorator() { 1553 return (target: any, key: any, descriptor: PropertyDescriptor) => descriptor; 1554} 1555class Foo { 1556 @decorator() 1557 // comment 1558 [#|method|]() { 1559 return fetch('a').then(x => x); 1560 } 1561} 1562`); 1563 1564 _testConvertToAsyncFunction("convertToAsyncFunction_decoratedMethodWithMultipleLineComment", ` 1565function decorator() { 1566 return (target: any, key: any, descriptor: PropertyDescriptor) => descriptor; 1567} 1568class Foo { 1569 @decorator() 1570 /** 1571 * comment 1572 */ 1573 [#|method|]() { 1574 return fetch('a').then(x => x); 1575 } 1576} 1577`); 1578 1579 _testConvertToAsyncFunction("convertToAsyncFunction_decoratedMethodWithModifier", ` 1580function decorator() { 1581 return (target: any, key: any, descriptor: PropertyDescriptor) => descriptor; 1582} 1583class Foo { 1584 @decorator() 1585 public [#|method|]() { 1586 return fetch('a').then(x => x); 1587 } 1588} 1589`); 1590 1591 _testConvertToAsyncFunctionFailedSuggestion("convertToAsyncFunction_OutermostOnlyFailure", ` 1592function foo() { 1593 return fetch('a').then([#|() => {|] 1594 return fetch('b').then(() => 'c'); 1595 }) 1596} 1597`); 1598 1599 _testConvertToAsyncFunction("convertToAsyncFunction_thenTypeArgument1", ` 1600type APIResponse<T> = { success: true, data: T } | { success: false }; 1601 1602function wrapResponse<T>(response: T): APIResponse<T> { 1603 return { success: true, data: response }; 1604} 1605 1606function [#|get|]() { 1607 return Promise.resolve(undefined!).then<APIResponse<{ email: string }>>(wrapResponse); 1608} 1609`); 1610 1611 _testConvertToAsyncFunction("convertToAsyncFunction_thenTypeArgument2", ` 1612type APIResponse<T> = { success: true, data: T } | { success: false }; 1613 1614function wrapResponse<T>(response: T): APIResponse<T> { 1615 return { success: true, data: response }; 1616} 1617 1618function [#|get|]() { 1619 return Promise.resolve(undefined!).then<APIResponse<{ email: string }>>(d => wrapResponse(d)); 1620} 1621`); 1622 1623 _testConvertToAsyncFunction("convertToAsyncFunction_thenTypeArgument3", ` 1624type APIResponse<T> = { success: true, data: T } | { success: false }; 1625 1626function wrapResponse<T>(response: T): APIResponse<T> { 1627 return { success: true, data: response }; 1628} 1629 1630function [#|get|]() { 1631 return Promise.resolve(undefined!).then<APIResponse<{ email: string }>>(d => { 1632 console.log(d); 1633 return wrapResponse(d); 1634 }); 1635} 1636`); 1637 1638 _testConvertToAsyncFunction("convertToAsyncFunction_catchTypeArgument1", ` 1639type APIResponse<T> = { success: true, data: T } | { success: false }; 1640 1641function [#|get|]() { 1642 return Promise 1643 .resolve<APIResponse<{ email: string }>>({ success: true, data: { email: "" } }) 1644 .catch<APIResponse<{ email: string }>>(() => ({ success: false })); 1645} 1646`); 1647 1648 _testConvertToAsyncFunctionFailed("convertToAsyncFunction_threeArguments", ` 1649function [#|f|]() { 1650 return Promise.resolve().then(undefined, undefined, () => 1); 1651}`); 1652 1653 _testConvertToAsyncFunction("convertToAsyncFunction_callbackArgument", ` 1654function foo(props: any): void { 1655 return props; 1656} 1657 1658const fn = (): Promise<(message: string) => void> => 1659 new Promise(resolve => resolve((message: string) => foo(message))); 1660 1661function [#|f|]() { 1662 return fn().then(res => res("test")); 1663} 1664`); 1665 1666 _testConvertToAsyncFunction("convertToAsyncFunction_emptyCatch1", ` 1667function [#|f|]() { 1668 return Promise.resolve().catch(); 1669} 1670`); 1671 1672 _testConvertToAsyncFunction("convertToAsyncFunction_emptyCatch2", ` 1673function [#|f|]() { 1674 return Promise.resolve(0).then(x => x).catch(); 1675} 1676`); 1677 1678 _testConvertToAsyncFunctionWithModule("convertToAsyncFunction_importedFunction", ` 1679import { fn } from "./module"; 1680function [#|f|]() { 1681 return Promise.resolve(0).then(fn); 1682} 1683`); 1684 1685 }); 1686} 1687