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