File
Blob: types/test/transforms/globals.spec.ts
| 1 | // Copyright (c) 2022-2023 Cloudflare, Inc. |
| 2 | // Licensed under the Apache 2.0 license found in the LICENSE file or at: |
| 3 | // https://opensource.org/licenses/Apache-2.0 |
| 4 | |
| 5 | import assert from "assert"; |
| 6 | import { test } from "node:test"; |
| 7 | import path from "path"; |
| 8 | import ts from "typescript"; |
| 9 | import { printer } from "../../src/print"; |
| 10 | import { createMemoryProgram } from "../../src/program"; |
| 11 | import { createGlobalScopeTransformer } from "../../src/transforms"; |
| 12 | |
| 13 | test("createGlobalScopeTransformer: extracts global scope", () => { |
| 14 | const source = `type WorkerGlobalScopeEventMap = { |
| 15 | fetch: Event; |
| 16 | scheduled: Event; |
| 17 | }; |
| 18 | declare class EventTarget<EventMap extends Record<string, Event> = Record<string, Event>> { |
| 19 | constructor(); |
| 20 | addEventListener<Type extends keyof EventMap>(type: Type, handler: (event: EventMap[Type]) => void): void; // MethodDeclaration |
| 21 | removeEventListener<Type extends keyof EventMap>(type: Type, handler: (event: EventMap[Type]) => void): void; // MethodDeclaration |
| 22 | dispatchEvent(event: EventMap[keyof EventMap]): void; // MethodDeclaration |
| 23 | } |
| 24 | declare class WorkerGlobalScope extends EventTarget<WorkerGlobalScopeEventMap> { |
| 25 | thing: string; // PropertyDeclaration |
| 26 | static readonly CONSTANT: 42; // PropertyDeclaration |
| 27 | get property(): number; // GetAccessorDeclaration |
| 28 | set property(value: number); // GetAccessorDeclaration |
| 29 | } |
| 30 | declare class DOMException { |
| 31 | } |
| 32 | declare abstract class Crypto { |
| 33 | } |
| 34 | declare abstract class Console { |
| 35 | } |
| 36 | interface ServiceWorkerGlobalScope extends WorkerGlobalScope { |
| 37 | DOMException: typeof DOMException; // PropertySignature |
| 38 | btoa(value: string): string; // MethodSignature |
| 39 | crypto: Crypto; // PropertySignature |
| 40 | get console(): Console; // GetAccessorDeclaration |
| 41 | } |
| 42 | `; |
| 43 | |
| 44 | const sourcePath = path.resolve(__dirname, "source.ts"); |
| 45 | const sources = new Map([[sourcePath, source]]); |
| 46 | const program = createMemoryProgram(sources); |
| 47 | const checker = program.getTypeChecker(); |
| 48 | const sourceFile = program.getSourceFile(sourcePath); |
| 49 | assert(sourceFile !== undefined); |
| 50 | |
| 51 | const result = ts.transform(sourceFile, [ |
| 52 | createGlobalScopeTransformer(checker), |
| 53 | ]); |
| 54 | assert.strictEqual(result.transformed.length, 1); |
| 55 | |
| 56 | const output = printer.printFile(result.transformed[0]); |
| 57 | assert.strictEqual( |
| 58 | output, |
| 59 | // Extracted global nodes inserted after ServiceWorkerGlobalScope |
| 60 | source + |
| 61 | `declare function addEventListener<Type extends keyof WorkerGlobalScopeEventMap>(type: Type, handler: (event: WorkerGlobalScopeEventMap[Type]) => void): void; |
| 62 | declare function removeEventListener<Type extends keyof WorkerGlobalScopeEventMap>(type: Type, handler: (event: WorkerGlobalScopeEventMap[Type]) => void): void; |
| 63 | declare function dispatchEvent(event: WorkerGlobalScopeEventMap[keyof WorkerGlobalScopeEventMap]): void; |
| 64 | declare const thing: string; |
| 65 | declare const CONSTANT: 42; |
| 66 | declare const property: number; |
| 67 | declare function btoa(value: string): string; |
| 68 | declare const crypto: Crypto; |
| 69 | declare const console: Console; |
| 70 | ` |
| 71 | ); |
| 72 | }); |
| 73 | |
| 74 | test("createGlobalScopeTransformer: inlining type parameters in heritage", () => { |
| 75 | const source = `declare class A<T> { |
| 76 | thing: T; |
| 77 | } |
| 78 | declare class B<T> extends A<T> { |
| 79 | } |
| 80 | declare class ServiceWorkerGlobalScope extends B<string> { |
| 81 | } |
| 82 | `; |
| 83 | |
| 84 | const sourcePath = path.resolve(__dirname, "source.ts"); |
| 85 | const sources = new Map([[sourcePath, source]]); |
| 86 | const program = createMemoryProgram(sources); |
| 87 | const checker = program.getTypeChecker(); |
| 88 | const sourceFile = program.getSourceFile(sourcePath); |
| 89 | assert(sourceFile !== undefined); |
| 90 | |
| 91 | const result = ts.transform(sourceFile, [ |
| 92 | createGlobalScopeTransformer(checker), |
| 93 | ]); |
| 94 | assert.strictEqual(result.transformed.length, 1); |
| 95 | |
| 96 | const output = printer.printFile(result.transformed[0]); |
| 97 | assert.strictEqual( |
| 98 | output, |
| 99 | source + |
| 100 | `declare const thing: string; |
| 101 | ` |
| 102 | ); |
| 103 | }); |