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