diff options
author | 2023-03-22 15:01:01 -0700 | |
---|---|---|
committer | 2023-03-22 15:01:01 -0700 | |
commit | a5f92224b586289fc72f0abdb68b08eef9f017db (patch) | |
tree | 6092397858776820b431b0dffa635d8bc3b3185e | |
parent | 2bdaa81b1c2325687c5115b4e97627533cb3646b (diff) | |
download | bun-a5f92224b586289fc72f0abdb68b08eef9f017db.tar.gz bun-a5f92224b586289fc72f0abdb68b08eef9f017db.tar.zst bun-a5f92224b586289fc72f0abdb68b08eef9f017db.zip |
Fix types (#2453)
* WIP
* WIP
* WIP
* WIP
* Improve typechecking in type files
* Fix typechecking
* Update
* Update submodule
* CI for typechecking
* Add ci
* Update commands
* Format after build
* Dont use bunx
* Rename job
* Use nodemodules prettier
* Update workflow
* Use symlink
* Debug
* Debug
* Clean up and rename jobs
76 files changed, 510 insertions, 271 deletions
diff --git a/.github/workflows/bun-typecheck.yml b/.github/workflows/bun-typecheck.yml new file mode 100644 index 000000000..4146dea09 --- /dev/null +++ b/.github/workflows/bun-typecheck.yml @@ -0,0 +1,31 @@ +name: typecheck +on: + push: + branches: [main] + paths: + - "packages/bun-types/**" + - "test/**" + + pull_request: + paths: + - "packages/bun-types/**" + - "test/**" + +jobs: + tests: + name: check-tests + runs-on: ubuntu-latest + defaults: + run: + working-directory: test + steps: + - name: Checkout repo + uses: actions/checkout@v3 + - name: Install bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: canary + - name: Install dependencies + run: bun install + - name: Typecheck tests + run: bun run typecheck diff --git a/.github/workflows/bun-types-tests.yml b/.github/workflows/bun-types-tests.yml index f95b2d866..bf3f591aa 100644 --- a/.github/workflows/bun-types-tests.yml +++ b/.github/workflows/bun-types-tests.yml @@ -1,4 +1,4 @@ -name: Test bun-types +name: bun-types on: push: paths: @@ -10,7 +10,7 @@ on: jobs: tests: - name: Build and test + name: type-tests runs-on: ubuntu-latest defaults: run: @@ -31,7 +31,8 @@ jobs: node-version: latest - name: Install dependencies - run: bun install + run: | + bun install - name: Generate package run: bun run build diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index f45a672ea..099603d59 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,7 +2,9 @@ "configurations": [ { "name": "Mac", - "forcedInclude": ["${workspaceFolder}/src/bun.js/bindings/root.h"], + "forcedInclude": [ + "${workspaceFolder}/src/bun.js/bindings/root.h" + ], "includePath": [ "${workspaceFolder}/../webkit-build/include/", "${workspaceFolder}/bun-webkit/include/", @@ -18,7 +20,6 @@ "${workspaceFolder}/src/bun.js/builtins/", "${workspaceFolder}/src/bun.js/builtins/cpp", "${workspaceFolder}/src/deps/boringssl/include/", - "${workspaceFolder}/src/deps", "${workspaceFolder}/src/deps/uws/uSockets/src" ], Binary files differdiff --git a/docs/index.md b/docs/index.md index 0426981c0..eaaf50628 100644 --- a/docs/index.md +++ b/docs/index.md @@ -21,7 +21,7 @@ $ bunx cowsay "Hello, world!" # execute a package ### Get started -{% block className="gap-[10px] grid grid-flow-row grid-cols-1 md:grid-cols-2" %} +{% block className="gap-2 grid grid-flow-row grid-cols-1 md:grid-cols-2" %} {% arrowbutton href="/docs/installation" text="Install Bun" /%} {% arrowbutton href="/docs/quickstart" text="Do the quickstart" /%} {% arrowbutton href="/docs/cli/install" text="Install a package" /%} diff --git a/docs/project/benchmarking.md b/docs/project/benchmarking.md index 0e3578237..b9672f325 100644 --- a/docs/project/benchmarking.md +++ b/docs/project/benchmarking.md @@ -18,8 +18,6 @@ When writing your own benchmarks, it's important to choose the right tool. - [`http_load_test`](https://github.com/uNetworking/uSockets/blob/master/examples/http_load_test.c) - For benchmarking scripts or CLI commands, we recommend [`hyperfine`](https://github.com/sharkdp/hyperfine). It's an easy way to compare -Recommended HTTP clients: - ## Measuring memory usage diff --git a/examples/http-file-extended.ts b/examples/http-file-extended.ts index 7ae515f14..14886af5e 100644 --- a/examples/http-file-extended.ts +++ b/examples/http-file-extended.ts @@ -29,7 +29,7 @@ serve({ if (req.headers.has("range")) { opts.code = 206; - let [x, y] = req.headers.get("range").replace("bytes=", "").split("-"); + let [x, y] = req.headers.get("range")!.replace("bytes=", "").split("-"); let end = (opts.end = parseInt(y, 10) || stats.size - 1); let start = (opts.start = parseInt(x, 10) || 0); diff --git a/examples/lambda.ts b/examples/lambda.ts index 66746ecad..ec4817817 100644 --- a/examples/lambda.ts +++ b/examples/lambda.ts @@ -9,6 +9,9 @@ const sourceDir = LAMBDA_TASK_ROOT; if (!sourceDir) { throw new Error("handler is not set"); } +if (!_HANDLER) { + throw new Error("handler is not set"); +} // don't care if this fails if (process.cwd() !== sourceDir) { diff --git a/examples/react-file-system-router/index.tsx b/examples/react-file-system-router/index.tsx index 62d1151d5..2abcc6b7e 100644 --- a/examples/react-file-system-router/index.tsx +++ b/examples/react-file-system-router/index.tsx @@ -14,7 +14,7 @@ export default { const route = router.match(request); - const { default: Root } = await import(route.filePath); + const { default: Root } = await import(route.filePath!); return new Response(await renderToReadableStream(<Root {...route.params} />)); }, }; diff --git a/examples/ssl.ts b/examples/ssl.ts index df30a0bd6..b886649e8 100644 --- a/examples/ssl.ts +++ b/examples/ssl.ts @@ -1,4 +1,5 @@ import { resolve } from "path"; +import type { ServeOptions } from "bun"; const development = process.env.NODE_ENV !== "production"; export default { @@ -11,4 +12,4 @@ export default { keyFile: process.env.SSL_KEY_FILE || "./key.pem", certFile: process.env.SSL_CERTIFICATE_FILE || "./cert.pem", development, -} as Bun.Serve; +} as ServeOptions; diff --git a/package.json b/package.json index 37d02bca0..e488635c2 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,14 @@ "prettier": "^2.4.1", "react": "next", "react-dom": "next", - "typescript": "latest" + "typescript": "^5.0.2" }, "private": true, "scripts": { "build-runtime": "esbuild --target=esnext --bundle src/runtime/index.ts --format=iife --platform=browser --global-name=BUN_RUNTIME > src/runtime.out.js; cat src/runtime.footer.js >> src/runtime.out.js", "build-fallback": "esbuild --target=esnext --bundle src/fallback.ts --format=iife --platform=browser --minify > src/fallback.out.js", "postinstall": "bash .scripts/postinstall.sh", - "typecheck": "tsc", + "typecheck": "tsc --noEmit", "fmt": "prettier --write './test/**/*.{mjs,ts,tsx,js,jsx}' './src/*.{mjs,ts,tsx,js,jsx}' './src/*/*.{mjs,ts,tsx,js,jsx}' './src/*/*/*.{mjs,ts,tsx,js,jsx}' './bench/*.{mjs,ts,tsx,js,jsx}' --config .prettierrc.cjs", "lint": "eslint './**/*.d.ts' --cache", "lint:fix": "eslint './**/*.d.ts' --cache --fix" diff --git a/packages/bun-types/bun-test.d.ts b/packages/bun-types/bun-test.d.ts index 16b4cf90c..181d4c79d 100644 --- a/packages/bun-types/bun-test.d.ts +++ b/packages/bun-types/bun-test.d.ts @@ -199,7 +199,12 @@ declare module "bun:test" { * * @param actual the actual value */ - export function expect(actual: unknown): Expect; + export const expect: { + (actual: unknown): Expect; + any: ( + constructor: ((..._: any[]) => any) | { new (..._: any[]): any }, + ) => Expect; + }; /** * Asserts that a value matches some criteria. * @@ -211,7 +216,7 @@ declare module "bun:test" { * * @param actual the actual value */ - export type Expect = { + export type Expect<T = unknown> = { /** * Negates the result of a subsequent assertion. * @@ -219,7 +224,7 @@ declare module "bun:test" { * expect(1).not.toBe(0); * expect(null).not.toBeNull(); */ - not: Expect; + not: Expect<unknown>; /** * Asserts that a value equals what is expected. * @@ -235,7 +240,7 @@ declare module "bun:test" { * * @param expected the expected value */ - toBe(expected: unknown): void; + toBe(expected: T): void; /** * Asserts that a value is deeply equal to what is expected. * @@ -247,7 +252,7 @@ declare module "bun:test" { * * @param expected the expected value */ - toEqual(expected: unknown): void; + toEqual(expected: T): void; /** * Asserts that a value is deeply and strictly equal to * what is expected. @@ -271,7 +276,7 @@ declare module "bun:test" { * * @param expected the expected value */ - toStrictEqual(expected: unknown): void; + toStrictEqual(expected: T): void; /** * Asserts that a value contains what is expected. * @@ -341,7 +346,15 @@ declare module "bun:test" { * expect(undefined).toBeDefined(); // fail */ toBeDefined(): void; - /** + /** + * Asserts that the expected value is an instance of value + * + * @example + * expect([]).toBeInstanceOf(Array); + * expect(null).toBeInstanceOf(Array); // fail + */ + toBeInstanceOf(value: unknown): void; + /** * Asserts that the expected value is an instance of value * * @example @@ -462,7 +475,7 @@ declare module "bun:test" { * @param hint Hint used to identify the snapshot in the snapshot file. */ toMatchSnapshot(propertyMatchers?: Object, hint?: string): void; - } + }; } declare module "test" { diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index 3773d3ebb..1768432df 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -500,7 +500,7 @@ declare module "bun" { * `"system"` uses the same API underneath (except non-blocking). * */ - backend?: "c-ares" | "system" | "getaddrinfo"; + backend?: "libc" | "c-ares" | "system" | "getaddrinfo"; }, ): Promise<DNSLookup[]>; }; @@ -1492,6 +1492,7 @@ declare module "bun" { ) => Response | Promise<Response> | undefined | void | Promise<undefined>; } + export type AnyFunction = (..._: any[]) => any; export interface ServeOptions extends GenericServeOptions { /** * Handle HTTP requests @@ -2819,7 +2820,7 @@ declare module "bun" { reload(options: Pick<Partial<SocketOptions>, "socket">): void; data: Data; } - interface TCPSocketListener<Data> extends SocketListener<Data> { + interface TCPSocketListener<Data = unknown> extends SocketListener<Data> { readonly port: number; readonly hostname: string; } @@ -3170,6 +3171,8 @@ declare module "bun" { /** The base path to use when routing */ assetPrefix?: string; origin?: string; + /** Limit the pages to those with particular file extensions. */ + fileExtensions?: string[]; }); // todo: URL @@ -3365,7 +3368,9 @@ type TypedArray = | Int32Array | Uint32Array | Float32Array - | Float64Array; + | Float64Array + | BigInt64Array + | BigUint64Array; type TimeLike = string | number | Date; type StringOrBuffer = string | TypedArray | ArrayBufferLike; diff --git a/packages/bun-types/bun.lockb b/packages/bun-types/bun.lockb Binary files differindex e764f6a0c..066d286b9 100755 --- a/packages/bun-types/bun.lockb +++ b/packages/bun-types/bun.lockb diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index 82f8cfb8b..6ff2e9970 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -417,7 +417,7 @@ interface BlobInterface { formData(): Promise<FormData>; } -type BlobPart = string | Blob | BufferSource | ArrayBuffer; +type BlobPart = string | Blob | BufferSource; interface BlobPropertyBag { /** Set a default "type" */ type?: string; @@ -639,7 +639,7 @@ declare class Blob implements BlobInterface { interface ResponseInit { headers?: HeadersInit; /** @default 200 */ - status?: number; + status?: number | bigint; /** @default "OK" */ statusText?: string; @@ -663,7 +663,13 @@ interface ResponseInit { */ declare class Response implements BlobInterface { constructor( - body?: ReadableStream | BlobPart | BlobPart[] | null | FormData, + body?: + | ReadableStream + | BlobPart + | BlobPart[] + | FormData + | URLSearchParams + | null, options?: ResponseInit, ); @@ -851,9 +857,9 @@ type ReferrerPolicy = | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url"; -type RequestInfo = Request | string | RequestInit; +// type RequestInfo = Request | string | RequestInit; -type BodyInit = ReadableStream | XMLHttpRequestBodyInit; +type BodyInit = ReadableStream | XMLHttpRequestBodyInit | URLSearchParams; type XMLHttpRequestBodyInit = Blob | BufferSource | string | FormData; type ReadableStreamController<T> = ReadableStreamDefaultController<T>; type ReadableStreamDefaultReadResult<T> = @@ -962,7 +968,10 @@ interface FetchRequestInit extends RequestInit { * ``` */ declare class Request implements BlobInterface { - constructor(requestInfo: RequestInfo, requestInit?: RequestInit); + // Request | string | RequestInit; + constructor(requestInfo: string, requestInit?: RequestInit); + constructor(requestInfo: RequestInit & { url: string }); + constructor(requestInfo: Request, requestInit?: RequestInit); /** * Read or write the HTTP headers for this request. @@ -1375,7 +1384,7 @@ declare function clearImmediate(id?: number | Timer): void; */ declare function fetch( - url: string | URL, + url: string | URL | Request, init?: FetchRequestInit, ): Promise<Response>; @@ -1584,7 +1593,7 @@ declare var EventTarget: { }; /** An event which takes place in the DOM. */ -interface Event { +interface Event<T extends EventTarget = EventTarget> { /** * Returns true or false depending on how event was initialized. True * if event goes through its target's ancestors in reverse tree order, @@ -1609,7 +1618,7 @@ interface Event { * Returns the object whose event listener's callback is currently * being invoked. */ - readonly currentTarget: EventTarget | null; + readonly currentTarget: T | null; /** * Returns true if preventDefault() was invoked successfully to * indicate cancelation, and false otherwise. @@ -1909,6 +1918,7 @@ interface URLSearchParams { ): void; /** Returns a string containing a query string suitable for use in a URL. Does not include the question mark. */ toString(): string; + [Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>; } declare var URLSearchParams: { @@ -1957,7 +1967,7 @@ interface EventMap { } interface AbortSignalEventMap { - abort: Event; + abort: Event<AbortSignal>; } interface AddEventListenerOptions extends EventListenerOptions { @@ -1972,10 +1982,12 @@ interface AbortSignal extends EventTarget { * Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise. */ readonly aborted: boolean; + /** * The reason the signal aborted, or undefined if not aborted. */ readonly reason: any; + onabort: ((this: AbortSignal, ev: Event) => any) | null; addEventListener<K extends keyof AbortSignalEventMap>( type: K, @@ -2157,7 +2169,11 @@ interface ReadableStream<R = any> { declare var ReadableStream: { prototype: ReadableStream; new <R = any>( - underlyingSource?: DirectUnderlyingSource<R> | UnderlyingSource<R>, + underlyingSource?: UnderlyingSource<R>, + strategy?: QueuingStrategy<R>, + ): ReadableStream<R>; + new <R = any>( + underlyingSource?: DirectUnderlyingSource<R>, strategy?: QueuingStrategy<R>, ): ReadableStream<R>; }; diff --git a/packages/bun-types/package.json b/packages/bun-types/package.json index 2dbf1839d..059ab0bfc 100644 --- a/packages/bun-types/package.json +++ b/packages/bun-types/package.json @@ -1,20 +1,22 @@ { "name": "bun-types", - "types": "index.d.ts", - "private": true, "repository": "https://github.com/oven-sh/bun", + "devDependencies": { + "conditional-type-checks": "^1.0.6", + "prettier": "^2.4.1", + "tsd": "^0.22.0", + "typescript": "^5.0.2" + }, + "private": true, "scripts": { + "prebuild": "echo $(pwd)", "build": "rm -rf ./dist && bun run bundle && bun run fmt", "bundle": "bun scripts/bundle.ts ./dist", "test": "tsd", - "fmt": "prettier --write './**/*.{ts,tsx,js,jsx}'" - }, - "devDependencies": { - "conditional-type-checks": "^1.0.6", - "prettier": "^2.4.1", - "tsd": "^0.22.0" + "fmt": "echo $(which prettier) && prettier --write './**/*.{ts,tsx,js,jsx}'" }, "tsd": { "directory": "tests" - } + }, + "types": "index.d.ts" } diff --git a/packages/bun-types/tests/ffi.test-d.ts b/packages/bun-types/tests/ffi.test-d.ts index 105736134..43088c679 100644 --- a/packages/bun-types/tests/ffi.test-d.ts +++ b/packages/bun-types/tests/ffi.test-d.ts @@ -60,7 +60,7 @@ tsd.expectType<number>(lib.symbols.add(1, 2)); tc.assert< tc.IsExact< - typeof lib["symbols"]["allArgs"], + (typeof lib)["symbols"]["allArgs"], [ number, number, diff --git a/packages/bun-types/tests/globals.test-d.ts b/packages/bun-types/tests/globals.test-d.ts index c67aa4256..64b37be13 100644 --- a/packages/bun-types/tests/globals.test-d.ts +++ b/packages/bun-types/tests/globals.test-d.ts @@ -87,3 +87,9 @@ global.Bun; const er = new DOMException(); er.name; er.HIERARCHY_REQUEST_ERR; + +new Request(new Request("https://example.com"), {}); +new Request("", { method: "POST" }); + +Bun.sleepSync(1); // sleep for 1 ms (not recommended) +await Bun.sleep(1); // sleep for 1 ms (recommended) diff --git a/packages/bun-types/tests/http.test-d.ts b/packages/bun-types/tests/http.test-d.ts index d9754ac0c..aee0b3703 100644 --- a/packages/bun-types/tests/http.test-d.ts +++ b/packages/bun-types/tests/http.test-d.ts @@ -25,3 +25,9 @@ const req = http.request({ host: "localhost", port: 3000, method: "GET" }); req.abort; req.end(); export {}; + +// URLSearchParams should be iterable +const sp = new URLSearchParams("q=foo&bar=baz"); +for (const q of sp) { + console.log(q); +} diff --git a/src/cli/tsconfig-for-init.json b/src/cli/tsconfig-for-init.json index 30522c12f..5c0ced989 100644 --- a/src/cli/tsconfig-for-init.json +++ b/src/cli/tsconfig-for-init.json @@ -5,11 +5,11 @@ ], "module": "esnext", "target": "esnext", - "moduleResolution": "nodenext", + "moduleResolution": "bundler", "strict": true, "downlevelIteration": true, "skipLibCheck": true, - "jsx": "preserve", + "jsx": "react-jsx", "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "allowJs": true, diff --git a/test/README.md b/test/README.md index 36fe3b005..03f9c97af 100644 --- a/test/README.md +++ b/test/README.md @@ -71,3 +71,13 @@ In the future, a bot will automatically close or re-open issues when a regressio These tests live in various `.zig` files throughout Bun's codebase, leveraging Zig's builtin `test` keyword. Currently, they're not run automatically nor is there a simple way to run all of them. We will make this better soon. + +## TypeScript + +Test files should be written in TypeScript. The types in `packages/bun-types` should be updated to support all new APIs. Changes to the `.d.ts` files in `packages/bun-types` will be immediately reflected in test files; no build step is necessary. + +Writing a test will often require using invalid syntax, e.g. when checking for errors when an invalid input is passed to a function. TypeScript provides a number of escape hatches here. + +- `// @ts-expect-error` - This should be your first choice. It tells TypeScript that the next line *should* fail typechecking. +- `// @ts-ignore` - Ignore the next line entirely. +- `// @ts-nocheck` - Put this at the top of the file to disable typechecking on the entire file. Useful for autogenerated test files, or when ignoring/disabling type checks an a per-line basis is too onerous. diff --git a/test/bun.lockb b/test/bun.lockb Binary files differindex ced88bdbb..e9e97d1aa 100755 --- a/test/bun.lockb +++ b/test/bun.lockb diff --git a/test/cli/hot/hot.test.ts b/test/cli/hot/hot.test.ts index 88c7977f7..7888f0308 100644 --- a/test/cli/hot/hot.test.ts +++ b/test/cli/hot/hot.test.ts @@ -64,11 +64,12 @@ it("should recover from errors", async () => { var queue = [onReloadError, onReloadGood, onReloadError, onReloadGood]; var errors: string[] = []; - var onError; + var onError: (...args: any[]) => void; (async () => { for await (let line of runner.stderr!) { var str = new TextDecoder().decode(line); errors.push(str); + // @ts-ignore onError && onError(str); } })(); diff --git a/test/cli/install/bun-add.test.ts b/test/cli/install/bun-add.test.ts index 310341560..0f3f13895 100644 --- a/test/cli/install/bun-add.test.ts +++ b/test/cli/install/bun-add.test.ts @@ -20,7 +20,7 @@ import { beforeAll(dummyBeforeAll); afterAll(dummyAfterAll); -let add_dir; +let add_dir: string; beforeEach(async () => { add_dir = await mkdtemp(join(await realpath(tmpdir()), "bun-add.test")); @@ -860,7 +860,7 @@ it("should handle Git URL in dependencies (SCP-style)", async () => { }); it("should prefer optionalDependencies over dependencies of the same name", async () => { - const urls = []; + const urls: string[] = []; setHandler( dummyRegistry(urls, { "0.0.2": { @@ -920,7 +920,7 @@ it("should prefer optionalDependencies over dependencies of the same name", asyn }); it("should prefer dependencies over peerDependencies of the same name", async () => { - const urls = []; + const urls: string[] = []; setHandler( dummyRegistry(urls, { "0.0.2": { diff --git a/test/cli/install/bun-link.test.ts b/test/cli/install/bun-link.test.ts index 5b0abe139..e79f09aaf 100644 --- a/test/cli/install/bun-link.test.ts +++ b/test/cli/install/bun-link.test.ts @@ -16,7 +16,7 @@ import { beforeAll(dummyBeforeAll); afterAll(dummyAfterAll); -let link_dir; +let link_dir: string; beforeEach(async () => { link_dir = await mkdtemp(join(await realpath(tmpdir()), "bun-link.test")); diff --git a/test/cli/install/bunx.test.ts b/test/cli/install/bunx.test.ts index 49d6e1c2d..87ad2f8b4 100644 --- a/test/cli/install/bunx.test.ts +++ b/test/cli/install/bunx.test.ts @@ -7,7 +7,7 @@ import { tmpdir } from "os"; import { join } from "path"; import { readdirSorted } from "./dummy.registry"; -let x_dir; +let x_dir: string; beforeEach(async () => { x_dir = realpathSync(await mkdtemp(join(tmpdir(), "bun-x.test"))); diff --git a/test/cli/install/dummy.registry.ts b/test/cli/install/dummy.registry.ts index 7d3acb612..d9496b0e7 100644 --- a/test/cli/install/dummy.registry.ts +++ b/test/cli/install/dummy.registry.ts @@ -11,12 +11,23 @@ import { mkdtemp, readdir, realpath, rm, writeFile } from "fs/promises"; import { tmpdir } from "os"; import { basename, join } from "path"; -type RequestHandler = (request: Request) => Response | Promise<Response>; -let handler: RequestHandler, server: Server; -export let package_dir: string, requested: number, root_url: string; +type Handler = (req: Request) => Response | Promise<Response>; +type Pkg = { + name: string; + version: string; + dist: { + tarball: string; + }; +}; +let handler: Handler; +let server: Server; let testCounter = 0; -export function dummyRegistry(urls: string[], info: any = { "0.0.2": {} }): RequestHandler { - return async request => { +export let package_dir: string; +export let requested: number; +export let root_url: string; + +export function dummyRegistry(urls: string[], info: any = { "0.0.2": {} }) { + const _handler: Handler = async request => { urls.push(request.url); expect(request.method).toBe("GET"); if (request.url.endsWith(".tgz")) { @@ -28,7 +39,7 @@ export function dummyRegistry(urls: string[], info: any = { "0.0.2": {} }): Requ expect(request.headers.get("npm-auth-type")).toBe(null); expect(await request.text()).toBe(""); const name = request.url.slice(request.url.indexOf("/", root_url.length) + 1); - const versions: any = {}; + const versions: Record<string, Pkg> = {}; let version; for (version in info) { if (!/^[0-9]/.test(version)) continue; @@ -51,6 +62,7 @@ export function dummyRegistry(urls: string[], info: any = { "0.0.2": {} }): Requ }), ); }; + return _handler; } export async function readdirSorted(path: PathLike): Promise<string[]> { @@ -59,11 +71,11 @@ export async function readdirSorted(path: PathLike): Promise<string[]> { return results; } -export function setHandler(newHandler: RequestHandler) { +export function setHandler(newHandler: Handler) { handler = newHandler; } -function resetHanlder() { +function resetHandler() { setHandler(() => new Response("Tea Break~", { status: 418 })); } @@ -86,7 +98,7 @@ var packageDirGetter: () => Promise<string> = async () => { return await realpath(await mkdtemp(join(await realpath(tmpdir()), "bun-install-test-" + testCounter++ + "--"))); }; export async function dummyBeforeEach() { - resetHanlder(); + resetHandler(); requested = 0; package_dir = await packageDirGetter(); @@ -101,7 +113,7 @@ registry = "http://localhost:${server.port}/" } export async function dummyAfterEach() { - resetHanlder(); + resetHandler(); await rm(package_dir, { force: true, recursive: true }); } diff --git a/test/cli/run/log-test.test.ts b/test/cli/run/log-test.test.ts index 2e980cb7b..55c7d6d86 100644 --- a/test/cli/run/log-test.test.ts +++ b/test/cli/run/log-test.test.ts @@ -35,7 +35,7 @@ it("should log .env by default", async () => { expect(stderr?.toString().includes(".env")).toBe(true); }); -function writeDirectoryTree(base, paths) { +function writeDirectoryTree(base: string, paths: Record<string, any>) { for (const path of Object.keys(paths)) { const content = paths[path]; const joined = join(base, path); diff --git a/test/js/bun/dns/resolve-dns.test.ts b/test/js/bun/dns/resolve-dns.test.ts index 52534da13..87d666616 100644 --- a/test/js/bun/dns/resolve-dns.test.ts +++ b/test/js/bun/dns/resolve-dns.test.ts @@ -3,7 +3,11 @@ import { describe, expect, it, test } from "bun:test"; import { withoutAggressiveGC } from "harness"; describe("dns.lookup", () => { - const backends = [process.platform === "darwin" ? "system" : undefined, "libc", "c-ares"].filter(Boolean); + const backends = [process.platform === "darwin" ? "system" : undefined, "libc", "c-ares"].filter(x => !!x) as ( + | "system" + | "libc" + | "c-ares" + )[]; for (let backend of backends) { it(backend + " parallell x 10", async () => { const promises = []; @@ -37,7 +41,7 @@ describe("dns.lookup", () => { try { await dns.lookup("yololololololo1234567.com", { backend }); throw 42; - } catch (e) { + } catch (e: any) { expect(typeof e).not.toBe("number"); expect(e.code).toBe("DNS_ENOTFOUND"); } diff --git a/test/js/bun/http/bun-server.test.ts b/test/js/bun/http/bun-server.test.ts index d260606e8..8c87ac422 100644 --- a/test/js/bun/http/bun-server.test.ts +++ b/test/js/bun/http/bun-server.test.ts @@ -158,6 +158,7 @@ describe("Server", () => { req.signal.addEventListener("abort", () => { signalOnServer = true; }); + return new Response( new ReadableStream({ async pull(controller) { diff --git a/test/js/bun/http/serve.leak.ts b/test/js/bun/http/serve.leak.ts index a7b8a44f6..d8711738a 100644 --- a/test/js/bun/http/serve.leak.ts +++ b/test/js/bun/http/serve.leak.ts @@ -1,3 +1,4 @@ +import type { Serve } from "bun"; import { heapStats } from "bun:jsc"; var prevCounts: Record<string, number>; export default { @@ -26,4 +27,4 @@ export default { }, }); }, -}; +} satisfies Serve; diff --git a/test/js/bun/http/serve.test.ts b/test/js/bun/http/serve.test.ts index c049aad1a..51d91767e 100644 --- a/test/js/bun/http/serve.test.ts +++ b/test/js/bun/http/serve.test.ts @@ -3,13 +3,14 @@ import { afterEach, describe, it, expect, afterAll } from "bun:test"; import { readFileSync, writeFileSync } from "fs"; import { resolve } from "path"; +type Handler = (req: Request) => Response; afterEach(() => gc(true)); const count = 200; let port = 10000; let server: Server | undefined; -async function runTest({ port, ...serverOptions }: Serve<any>, test: (server: Serve<any>) => Promise<void> | void) { +async function runTest({ port, ...serverOptions }: Serve<any>, test: (server: Server) => Promise<void> | void) { if (server) { server.reload({ ...serverOptions, port: 0 }); } else { @@ -72,6 +73,7 @@ afterAll(() => { it("should display a welcome message when the response value type is incorrect", async () => { await runTest( { + // @ts-ignore fetch(req) { return Symbol("invalid response type"); }, @@ -116,7 +118,7 @@ it("request.signal works in trivial case", async () => { it("request.signal works in leaky case", async () => { var aborty = new AbortController(); var didAbort = false; - var leaky; + var leaky: Request | undefined; await runTest( { async fetch(req) { @@ -133,7 +135,7 @@ it("request.signal works in leaky case", async () => { await Bun.sleep(1); - leaky.signal.addEventListener("abort", () => { + leaky!.signal.addEventListener("abort", () => { didAbort = true; }); @@ -170,7 +172,7 @@ it("should work for a file", async () => { it("request.url should log successfully", async () => { const fixture = resolve(import.meta.dir, "./fetch.js.txt"); const textToExpect = readFileSync(fixture, "utf-8"); - var expected; + var expected: string; await runTest( { fetch(req) { @@ -379,7 +381,7 @@ describe("streaming", () => { it("text from JS throws on start has error handler", async () => { var pass = false; - var err; + var err: Error; await runTest( { error(e) { @@ -758,8 +760,8 @@ describe("parallel", () => { }); it("should support reloading", async () => { - const first = req => new Response("first"); - const second = req => new Response("second"); + const first: Handler = req => new Response("first"); + const second: Handler = req => new Response("second"); await runTest( { fetch: first, @@ -835,7 +837,7 @@ describe("status code text", () => { 508: "Loop Detected", 510: "Not Extended", 511: "Network Authentication Required", - }; + } as Record<string, string>; for (let code in fixture) { it(`should return ${code} ${fixture[code]}`, async () => { diff --git a/test/js/bun/net/socket.test.ts b/test/js/bun/net/socket.test.ts index f6b90db00..47b33d1d4 100644 --- a/test/js/bun/net/socket.test.ts +++ b/test/js/bun/net/socket.test.ts @@ -1,6 +1,6 @@ import { expect, it } from "bun:test"; import { bunEnv, bunExe, expectMaxObjectTypeCount } from "harness"; -import { connect, spawn } from "bun"; +import { connect, SocketHandler, spawn } from "bun"; it("should keep process alive only when active", async () => { const { exited, stdout, stderr } = spawn({ @@ -29,10 +29,11 @@ it("should keep process alive only when active", async () => { it("listen() should throw connection error for invalid host", () => { expect(() => { - const handlers = { + const handlers: SocketHandler = { open(socket) { - socket.close(); + socket.end(); }, + close() {}, data() {}, }; diff --git a/test/js/bun/plugin/plugins.test.ts b/test/js/bun/plugin/plugins.test.ts index 2bac4b4d4..79213239b 100644 --- a/test/js/bun/plugin/plugins.test.ts +++ b/test/js/bun/plugin/plugins.test.ts @@ -3,6 +3,16 @@ import { plugin } from "bun"; import { describe, expect, it } from "bun:test"; import { resolve } from "path"; +declare global { + var failingObject: any; + var objectModuleResult: any; + var laterCode: any; + var asyncOnLoad: any; + var asyncObject: any; + var asyncfail: any; + var asyncret: any; +} + plugin({ name: "boop beep beep", setup(builder) { diff --git a/test/js/bun/spawn/spawn-streaming-stdin.test.ts b/test/js/bun/spawn/spawn-streaming-stdin.test.ts index e2d346ec8..f69e7d9b6 100644 --- a/test/js/bun/spawn/spawn-streaming-stdin.test.ts +++ b/test/js/bun/spawn/spawn-streaming-stdin.test.ts @@ -19,13 +19,13 @@ test("spawn can write to stdin multiple chunks", async () => { exited = proc.exited; var counter = 0; var inCounter = 0; - var chunks = []; + var chunks: any[] = []; const prom = (async function () { try { - for await (var chunk of proc.stdout) { + for await (var chunk of proc.stdout!) { chunks.push(chunk); } - } catch (e) { + } catch (e: any) { console.log(e.stack); throw e; } @@ -33,13 +33,13 @@ test("spawn can write to stdin multiple chunks", async () => { const prom2 = (async function () { while (true) { - proc.stdin.write("Wrote to stdin!\n"); + proc.stdin!.write("Wrote to stdin!\n"); inCounter++; await new Promise(resolve => setTimeout(resolve, 8)); if (inCounter === 4) break; } - proc.stdin.end(); + proc.stdin!.end(); })(); await Promise.all([prom, prom2]); diff --git a/test/js/bun/spawn/spawn-streaming-stdout.test.ts b/test/js/bun/spawn/spawn-streaming-stdout.test.ts index 75e36ca2c..54c1451f0 100644 --- a/test/js/bun/spawn/spawn-streaming-stdout.test.ts +++ b/test/js/bun/spawn/spawn-streaming-stdout.test.ts @@ -21,12 +21,12 @@ test("spawn can read from stdout multiple chunks", async () => { var chunks = []; let counter = 0; try { - for await (var chunk of proc.stdout) { + for await (var chunk of proc.stdout!) { chunks.push(chunk); counter++; if (counter > 3) break; } - } catch (e) { + } catch (e: any) { console.log(e.stack); throw e; } diff --git a/test/js/bun/spawn/spawn.test.ts b/test/js/bun/spawn/spawn.test.ts index 876985e66..54b890d51 100644 --- a/test/js/bun/spawn/spawn.test.ts +++ b/test/js/bun/spawn/spawn.test.ts @@ -1,7 +1,7 @@ import { ArrayBufferSink, readableStreamToText, spawn, spawnSync, write } from "bun"; import { describe, expect, it } from "bun:test"; import { gcTick as _gcTick, bunEnv } from "harness"; -import { rmdirSync, unlinkSync, rmSync, writeFileSync } from "node:fs"; +import { rmSync, writeFileSync } from "node:fs"; for (let [gcTick, label] of [ [_gcTick, "gcTick"], diff --git a/test/js/bun/stream/direct-readable-stream.test.tsx b/test/js/bun/stream/direct-readable-stream.test.tsx index 9687e4082..1accb6d29 100644 --- a/test/js/bun/stream/direct-readable-stream.test.tsx +++ b/test/js/bun/stream/direct-readable-stream.test.tsx @@ -5,9 +5,11 @@ import { readableStreamToBlob, readableStreamToText, serve, + Server, } from "bun"; import { describe, expect, it } from "bun:test"; import { expectMaxObjectTypeCount, gc } from "harness"; +// @ts-ignore import { renderToReadableStream as renderToReadableStreamBrowser } from "react-dom/server.browser"; import { renderToReadableStream as renderToReadableStreamBun } from "react-dom/server"; import React from "react"; @@ -89,7 +91,7 @@ const fixtures = [ πLπlπLπ </>, ], -]; +] as const; describe("React", () => { it("React.createContext works", () => { @@ -243,7 +245,7 @@ describe("ReactDOM", () => { it(`http server, ${count} requests`, async () => { var remain = count; await (async () => { - let server; + let server!: Server; try { server = serve({ port: 0, diff --git a/test/js/bun/test/snapshot-tests/bun-snapshots.test.ts b/test/js/bun/test/snapshot-tests/bun-snapshots.test.ts index 7ed243491..a601ca556 100644 --- a/test/js/bun/test/snapshot-tests/bun-snapshots.test.ts +++ b/test/js/bun/test/snapshot-tests/bun-snapshots.test.ts @@ -1,3 +1,5 @@ +import { it, test, expect, describe } from "bun:test"; + test("it will create a snapshot file if it doesn't exist", () => { expect({ a: { b: { c: false } }, c: 2, jkfje: 99238 }).toMatchSnapshot({ a: { b: { c: expect.any(Boolean) } } }); expect({ a: { b: { c: "string" } }, c: 2, jkfje: 99238 }).toMatchSnapshot({ a: { b: { c: expect.any(String) } } }); @@ -37,6 +39,7 @@ describe("toMatchSnapshot errors", () => { }); it("should throw if arguments are in the wrong order", () => { expect(() => { + // @ts-expect-error expect({ a: "oops" }).toMatchSnapshot("wrong spot", { a: "oops" }); }).toThrow(); expect(() => { @@ -46,12 +49,15 @@ describe("toMatchSnapshot errors", () => { it("should throw if expect.any() doesn't received a constructor", () => { expect(() => { + // @ts-expect-error expect({ a: 4 }).toMatchSnapshot({ a: expect.any() }); }).toThrow(); expect(() => { + // @ts-expect-error expect({ a: 5 }).toMatchSnapshot({ a: expect.any(5) }); }).toThrow(); expect(() => { + // @ts-expect-error expect({ a: 4 }).toMatchSnapshot({ a: expect.any("not a constructor") }); }).toThrow(); }); diff --git a/test/js/bun/test/snapshot-tests/existing-snapshots.test.ts b/test/js/bun/test/snapshot-tests/existing-snapshots.test.ts index 30040e2f1..e09bee659 100644 --- a/test/js/bun/test/snapshot-tests/existing-snapshots.test.ts +++ b/test/js/bun/test/snapshot-tests/existing-snapshots.test.ts @@ -1,3 +1,5 @@ +import { it, test, expect, describe } from "bun:test"; + test("it will work with an existing snapshot file made with bun", () => { expect({ a: { b: { c: false } }, c: 2, jkfje: 99238 }).toMatchSnapshot({ a: { b: { c: expect.any(Boolean) } } }); expect({ a: { b: { c: "string" } }, c: 2, jkfje: 99238 }).toMatchSnapshot({ a: { b: { c: expect.any(String) } } }); diff --git a/test/js/bun/test/snapshot-tests/new-snapshot.test.ts b/test/js/bun/test/snapshot-tests/new-snapshot.test.ts index a3a47ae82..51aa48a13 100644 --- a/test/js/bun/test/snapshot-tests/new-snapshot.test.ts +++ b/test/js/bun/test/snapshot-tests/new-snapshot.test.ts @@ -2,6 +2,8 @@ import fs from "fs"; import { bunExe } from "harness"; import { tmpdir } from "os"; +import { it, test, expect, describe } from "bun:test"; + test("it will create a snapshot file and directory if they don't exist", () => { const tempDir = tmpdir() + "/new-snapshot"; fs.rmSync(tempDir, { force: true, recursive: true }); diff --git a/test/js/bun/test/snapshot-tests/new-snapshot.ts b/test/js/bun/test/snapshot-tests/new-snapshot.ts index 378690a32..d7f55597d 100644 --- a/test/js/bun/test/snapshot-tests/new-snapshot.ts +++ b/test/js/bun/test/snapshot-tests/new-snapshot.ts @@ -1,3 +1,4 @@ +import { it, test, expect, describe } from "bun:test"; test("new snapshot", () => { expect({ b: 2 }).toMatchSnapshot(); }); diff --git a/test/js/bun/test/snapshot-tests/snapshots/more-snapshots/different-directory.test.ts b/test/js/bun/test/snapshot-tests/snapshots/more-snapshots/different-directory.test.ts index 6d29cf26f..6692d72d0 100644 --- a/test/js/bun/test/snapshot-tests/snapshots/more-snapshots/different-directory.test.ts +++ b/test/js/bun/test/snapshot-tests/snapshots/more-snapshots/different-directory.test.ts @@ -1,3 +1,5 @@ +import { it, test, expect, describe } from "bun:test"; + test("snapshots in different directory", () => { expect("1\b2\n3\r4").toMatchSnapshot(); expect("\r\n").toMatchSnapshot(); diff --git a/test/js/bun/test/snapshot-tests/snapshots/more.test.ts b/test/js/bun/test/snapshot-tests/snapshots/more.test.ts index 4cf0c8a1c..0922e4756 100644 --- a/test/js/bun/test/snapshot-tests/snapshots/more.test.ts +++ b/test/js/bun/test/snapshot-tests/snapshots/more.test.ts @@ -1,3 +1,4 @@ +import { it, test, expect, describe } from "bun:test"; describe("d0", () => { test("snapshot serialize edgecases", () => { expect(1).toMatchSnapshot(); diff --git a/test/js/bun/test/snapshot-tests/snapshots/moremore.test.ts b/test/js/bun/test/snapshot-tests/snapshots/moremore.test.ts index d3ed3da42..d54dcc6f7 100644 --- a/test/js/bun/test/snapshot-tests/snapshots/moremore.test.ts +++ b/test/js/bun/test/snapshot-tests/snapshots/moremore.test.ts @@ -1,22 +1,24 @@ +import { it, test, expect, describe } from "bun:test"; + class Number2 extends Number { - constructor(value) { + constructor(value: number) { super(value); } } class Number3 extends Number2 { - constructor(value) { + constructor(value: number) { super(value); } } class Boolean2 extends Boolean { - constructor(value) { + constructor(value: boolean) { super(value); } } class Boolean3 extends Boolean2 { - constructor(value) { + constructor(value: boolean) { super(value); } diff --git a/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts b/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts index e5a024379..519a0169f 100644 --- a/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts +++ b/test/js/bun/test/snapshot-tests/snapshots/snapshot.test.ts @@ -1,4 +1,6 @@ -function test1000000(arg1, arg218718132) {} +import { it, test, expect, describe } from "bun:test"; + +function test1000000(arg1: any, arg218718132: any) {} test("most types", () => { expect(test1000000).toMatchSnapshot("Function"); @@ -19,6 +21,7 @@ test("most types", () => { expect([[], [], [], []]).toMatchSnapshot("Array with multiple empty arrays"); expect([1, 2, [3, 4], [4, [5, 6]], 8]).toMatchSnapshot("Array with nested arrays"); let buf = new Buffer("hello"); + // @ts-ignore buf.x = "yyyyyyyyyy"; expect(buf).toMatchSnapshot("Buffer with property"); expect(new Buffer("hello")).toMatchSnapshot("Buffer2"); @@ -36,7 +39,7 @@ test("most types", () => { new Map([ [1, "eight"], ["seven", "312390840812"], - ]), + ] as any), ).toMatchSnapshot("Map"); expect(new Set()).toMatchSnapshot("Set"); expect(new Set([1, 2, 3, 4, 5, 6, 7, 8, 9])).toMatchSnapshot("Set2"); @@ -78,6 +81,7 @@ test("most types", () => { a = 1; b = 2; constructor() { + // @ts-ignore this.c = 3; } d() { @@ -87,6 +91,7 @@ test("most types", () => { return 5; } set e(value) { + // @ts-ignore this.f = value; } } diff --git a/test/js/bun/test/test-test.test.ts b/test/js/bun/test/test-test.test.ts index 6dc40f97c..90a305283 100644 --- a/test/js/bun/test/test-test.test.ts +++ b/test/js/bun/test/test-test.test.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import { spawn, spawnSync } from "bun"; import { describe, expect, it, test } from "bun:test"; import { mkdirSync, realpathSync, rmSync, writeFileSync } from "fs"; diff --git a/test/js/bun/util/filesink.test.ts b/test/js/bun/util/filesink.test.ts index 31fd70e54..1f41e3c56 100644 --- a/test/js/bun/util/filesink.test.ts +++ b/test/js/bun/util/filesink.test.ts @@ -41,7 +41,7 @@ describe("FileSink", () => { ], ] as const; - function getPath(label) { + function getPath(label: string) { const path = `/tmp/bun-test-${Bun.hash(label).toString(10)}.txt`; try { require("fs").unlinkSync(path); @@ -52,7 +52,7 @@ describe("FileSink", () => { var activeFIFO: Promise<string>; var decoder = new TextDecoder(); - function getFd(label) { + function getFd(label: string) { const path = `/tmp/bun-test-${Bun.hash(label).toString(10)}.txt`; try { require("fs").unlinkSync(path); diff --git a/test/js/bun/util/filesystem_router.test.ts b/test/js/bun/util/filesystem_router.test.ts index f5ee5c936..0cdb6a4cf 100644 --- a/test/js/bun/util/filesystem_router.test.ts +++ b/test/js/bun/util/filesystem_router.test.ts @@ -5,7 +5,7 @@ import fs, { mkdirSync, realpathSync, rmSync } from "fs"; import { tmpdir } from "os"; const tempdir = realpathSync(tmpdir()) + "/"; -function createTree(basedir, paths) { +function createTree(basedir: string, paths: string[]) { for (const end of paths) { const abs = path.join(basedir, end); try { @@ -16,7 +16,7 @@ function createTree(basedir, paths) { } } var count = 0; -function make(files) { +function make(files: string[]) { const dir = tempdir + `fs-router-test-${count++}`; rmSync(dir, { recursive: true, @@ -55,7 +55,7 @@ it("should find files", () => { }); const routes = router.routes; - const fixture = { + const fixture: Record<string, string> = { "/": `${dir}/index.tsx`, "/[id]": `${dir}/[id].tsx`, "/a": `${dir}/a.tsx`, @@ -94,6 +94,7 @@ it("should handle empty dirs", () => { }); // assert this doesn't crash + // @ts-ignore expect(router.bar).toBeUndefined(); const routes = router.routes; @@ -110,7 +111,7 @@ it("should match dynamic routes", () => { style: "nextjs", }); - const { name, filePath } = router.match("/posts/hello-world"); + const { name, filePath } = router.match("/posts/hello-world")!; expect(name).toBe("/posts/[id]"); expect(filePath).toBe(`${dir}/posts/[id].tsx`); @@ -127,7 +128,7 @@ it(".params works on dynamic routes", () => { const { params: { id }, - } = router.match("/posts/hello-world"); + } = router.match("/posts/hello-world")!; expect(id).toBe("hello-world"); }); @@ -141,7 +142,7 @@ it("should support static routes", () => { style: "nextjs", }); - const { name, params, filePath } = router.match("/posts/hey"); + const { name, params, filePath } = router.match("/posts/hey")!; expect(name).toBe("/posts/hey"); expect(filePath).toBe(`${dir}/posts/hey.tsx`); @@ -161,7 +162,7 @@ it("should support optional catch-all routes", () => { } for (let fixture of ["/posts/hey/there", "/posts/hey/there/you", "/posts/zorp/123"]) { - const { name, params, filePath } = router.match(fixture); + const { name, params, filePath } = router.match(fixture)!; expect(name).toBe("/posts/[[...id]]"); expect(filePath).toBe(`${dir}/posts/[[...id]].tsx`); @@ -186,11 +187,14 @@ it("should support catch-all routes", () => { }); for (let fixture of ["/posts/123", "/posts/hey", "/posts/zorp", "/posts", "/index", "/posts/"]) { - expect(router.match(fixture)?.name).not.toBe("/posts/[...id]"); + console.log(`matching ${fixture}`); + const match = router.match(fixture); + console.log(match); + expect(match?.name).not.toBe("/posts/[...id]"); } for (let fixture of ["/posts/hey/there", "/posts/hey/there/you", "/posts/zorp/123", "/posts/wow/hey/there"]) { - const { name, params, filePath } = router.match(fixture); + const { name, params, filePath } = router.match(fixture)!; expect(name).toBe("/posts/[...id]"); expect(filePath).toBe(`${dir}/posts/[...id].tsx`); @@ -208,7 +212,7 @@ it("should support index routes", () => { }); for (let route of ["/", "/index"]) { - const { name, params, filePath } = router.match(route); + const { name, params, filePath } = router.match(route)!; expect(name).toBe("/"); expect(filePath).toBe(`${dir}/index.tsx`); @@ -216,7 +220,7 @@ it("should support index routes", () => { } for (let route of ["/posts", "/posts/index", "/posts/"]) { - const { name, params, filePath } = router.match(route); + const { name, params, filePath } = router.match(route)!; expect(name).toBe("/posts"); expect(filePath).toBe(`${dir}/posts.tsx`); @@ -241,7 +245,7 @@ it("should support Request", async () => { name, params: { id }, filePath, - } = router.match(current); + } = router.match(current)!; expect(name).toBe("/posts/[id]"); expect(filePath).toBe(`${dir}/posts/[id].tsx`); expect(id).toBe("hello-world"); @@ -264,7 +268,13 @@ it("assetPrefix, src, and origin", async () => { new Request({ url: "http://helloooo.com/posts/hello-world" }), new Request({ url: "https://nextjs.org/posts/hello-world" }), ]) { - const { name, src, filePath, checkThisDoesntCrash } = router.match(current); + const { + name, + src, + filePath, + // @ts-ignore + checkThisDoesntCrash, + } = router.match(current)!; expect(name).toBe("/posts/[id]"); // check nothing is weird on the MatchedRoute object @@ -294,8 +304,15 @@ it(".query works", () => { { hello: "world", second: "2", third: "3" }, ], [new URL("https://example.com/posts").href, {}], - ]) { - const { name, src, filePath, checkThisDoesntCrash, query } = router.match(current); + ] as const) { + const { + name, + src, + filePath, + // @ts-ignore + checkThisDoesntCrash, + query, + } = router.match(current)!; expect(name).toBe("/posts"); // check nothing is weird on the MatchedRoute object @@ -317,9 +334,9 @@ it("reload() works", () => { origin: "https://nextjs.org", }); - expect(router.match("/posts").name).toBe("/posts"); + expect(router.match("/posts")!.name).toBe("/posts"); router.reload(); - expect(router.match("/posts").name).toBe("/posts"); + expect(router.match("/posts")!.name).toBe("/posts"); }); it(".query works with dynamic routes, including params", () => { @@ -341,8 +358,15 @@ it(".query works with dynamic routes, including params", () => { { id: "123", hello: "world", second: "2", third: "3" }, ], [new URL("https://example.com/posts/123").href, { id: "123" }], - ]) { - const { name, src, filePath, checkThisDoesntCrash, query } = router.match(current); + ] as const) { + const { + name, + src, + filePath, + // @ts-ignore + checkThisDoesntCrash, + query, + } = router.match(current)!; expect(name).toBe("/posts/[id]"); // check nothing is weird on the MatchedRoute object diff --git a/test/js/bun/util/sleepSync.test.ts b/test/js/bun/util/sleepSync.test.ts index dd2e8818a..e4204e1d3 100644 --- a/test/js/bun/util/sleepSync.test.ts +++ b/test/js/bun/util/sleepSync.test.ts @@ -10,17 +10,15 @@ it("sleepSync uses milliseconds", async () => { }); it("sleepSync with no arguments throws", async () => { + // @ts-expect-error expect(() => sleepSync()).toThrow(); }); it("sleepSync with non-numbers throws", async () => { - expect(() => sleepSync(true)).toThrow(); - expect(() => sleepSync(false)).toThrow(); - expect(() => sleepSync("hi")).toThrow(); - expect(() => sleepSync({})).toThrow(); - expect(() => sleepSync([])).toThrow(); - expect(() => sleepSync(undefined)).toThrow(); - expect(() => sleepSync(null)).toThrow(); + const invalidValues = [true, false, "hi", {}, [], undefined, null] as any[]; + for (const v of invalidValues) { + expect(() => sleepSync(v)).toThrow(); + } }); it("sleepSync with negative number throws", async () => { diff --git a/test/js/bun/util/which.test.ts b/test/js/bun/util/which.test.ts index e142e398c..3deeebd99 100644 --- a/test/js/bun/util/which.test.ts +++ b/test/js/bun/util/which.test.ts @@ -52,7 +52,7 @@ test("which", () => { } catch (e) {} }); -function writeFixture(path) { +function writeFixture(path: string) { var fs = require("fs"); try { fs.unlinkSync(path); diff --git a/test/js/bun/websocket/websocket-server.test.ts b/test/js/bun/websocket/websocket-server.test.ts index 47554a5f6..404eca8cf 100644 --- a/test/js/bun/websocket/websocket-server.test.ts +++ b/test/js/bun/websocket/websocket-server.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "bun:test"; import { gcTick } from "harness"; -import { serve } from "bun"; +import { serve, ServerWebSocket } from "bun"; describe("websocket server", () => { it("remoteAddress works", done => { @@ -80,7 +80,7 @@ describe("websocket server", () => { server.publish("all", "hello"); }, message(ws, msg) { - if (new TextDecoder().decode(msg) !== "hello") { + if (new TextDecoder().decode(msg as Uint8Array) !== "hello") { done(new Error("unexpected message")); } }, @@ -108,7 +108,7 @@ describe("websocket server", () => { done(); }); - for (let method of ["publish", "publishText", "publishBinary"]) { + for (let method of ["publish", "publishText", "publishBinary"] as const) { describe(method, () => { it("in close() should work", async () => { var count = 0; @@ -120,7 +120,7 @@ describe("websocket server", () => { }, message(ws, msg) {}, close(ws) { - ws[method]("all", method === "publishBinary" ? Buffer.from("bye!") : "bye!"); + (ws[method] as any)("all", method === "publishBinary" ? Buffer.from("bye!") : "bye!"); count++; if (count >= 2) { @@ -170,7 +170,7 @@ describe("websocket server", () => { } it("close inside open", async () => { - var resolve; + var resolve: () => void; console.trace("here"); var server = serve({ port: 0, @@ -574,7 +574,7 @@ describe("websocket server", () => { it("publishText()", async () => { await new Promise<void>((resolve, reject) => { - var websocket; + var websocket: WebSocket; var server = serve({ port: 0, websocket: { @@ -604,7 +604,7 @@ describe("websocket server", () => { const bytes = Buffer.from("hello"); await new Promise<void>((resolve, reject) => { - var websocket; + var websocket: WebSocket; var server = serve({ port: 0, websocket: { @@ -632,7 +632,7 @@ describe("websocket server", () => { it("sendText()", async () => { await new Promise<void>((resolve, reject) => { - var websocket; + var websocket: WebSocket; var server = serve({ port: 0, websocket: { @@ -660,7 +660,7 @@ describe("websocket server", () => { it("sendBinary()", async () => { const bytes = Buffer.from("hello"); await new Promise<void>((resolve, reject) => { - var websocket; + var websocket: WebSocket; var server = serve({ port: 0, websocket: { @@ -907,7 +907,10 @@ describe("websocket server", () => { await new Promise<void>(done => { for (var i = 0; i < connections.length; i++) { var j = i; - var resolve, reject, resolveConnection, rejectConnection; + var resolve: (_?: unknown) => void, + reject: (_?: unknown) => void, + resolveConnection: (_?: unknown) => void, + rejectConnection: (_?: unknown) => void; connections[j] = new Promise((res, rej) => { resolveConnection = res; rejectConnection = rej; diff --git a/test/js/node/child_process/child_process.test.ts b/test/js/node/child_process/child_process.test.ts index 167cbd8b0..c249c6434 100644 --- a/test/js/node/child_process/child_process.test.ts +++ b/test/js/node/child_process/child_process.test.ts @@ -4,14 +4,14 @@ import { ChildProcess, spawn, execFile, exec, fork, spawnSync, execFileSync, exe import { tmpdir } from "node:os"; import { promisify } from "node:util"; -const expect: typeof expect_ = (actual: unknown) => { +const expect = ((actual: unknown) => { gcTick(); const ret = expect_(actual); gcTick(); return ret; -}; +}) as typeof expect_; -const it: typeof it_ = (label, fn) => { +const it = ((label, fn) => { const hasDone = fn.length === 1; if (fn.constructor.name === "AsyncFunction" && hasDone) { return it_(label, async done => { @@ -38,7 +38,7 @@ const it: typeof it_ = (label, fn) => { gcTick(); }); } -}; +}) as typeof it_; const debug = process.env.DEBUG ? console.log : () => {}; @@ -56,6 +56,7 @@ describe("ChildProcess.spawn()", () => { proc.on("spawn", () => { resolve(true); }); + // @ts-ignore proc.spawn({ file: "bun", args: ["bun", "-v"] }); }); expect(result).toBe(true); @@ -67,7 +68,7 @@ describe("ChildProcess.spawn()", () => { proc.on("exit", () => { resolve(true); }); - + // @ts-ignore proc.spawn({ file: "bun", args: ["bun", "-v"] }); proc.kill(); }); @@ -174,14 +175,15 @@ describe("spawn()", () => { it("should allow us to timeout hanging processes", async () => { const child = spawn("sleep", ["2"], { timeout: 3 }); const start = performance.now(); - let end; + let end: number; await new Promise(resolve => { child.on("exit", () => { end = performance.now(); resolve(true); }); }); - expect(end - start < 2000).toBe(true); + expect(end!).toBeDefined(); + expect(end! - start < 2000).toBe(true); }); it("should allow us to set env", async () => { @@ -195,7 +197,7 @@ describe("spawn()", () => { }); it("should allow explicit setting of argv0", async () => { - var resolve; + var resolve: (_?: any) => void; const promise = new Promise<string>(resolve1 => { resolve = resolve1; }); diff --git a/test/js/node/crypto/crypto-scrypt.test.js b/test/js/node/crypto/crypto-scrypt.test.ts index 4b7412251..2330f5b85 100644 --- a/test/js/node/crypto/crypto-scrypt.test.js +++ b/test/js/node/crypto/crypto-scrypt.test.ts @@ -211,7 +211,7 @@ it("scrypt badargs", () => { try { crypto.scryptSync(...args); expect(() => {}).toThrow(); - } catch (e) { + } catch (e: any) { if (!("code" in e)) throw e; expect(e.code).toBe(expected.code); } diff --git a/test/js/node/crypto/crypto.test.js b/test/js/node/crypto/crypto.test.ts index b5b8e9286..b5b8e9286 100644 --- a/test/js/node/crypto/crypto.test.js +++ b/test/js/node/crypto/crypto.test.ts diff --git a/test/js/node/events/event-emitter.test.ts b/test/js/node/events/event-emitter.test.ts index e397faaed..401ccf605 100644 --- a/test/js/node/events/event-emitter.test.ts +++ b/test/js/node/events/event-emitter.test.ts @@ -100,7 +100,7 @@ const waysOfCreating = [ () => { const FakeEmitter: any = function FakeEmitter(this: any) { EventEmitter.call(this); - }; + } as any; Object.assign(FakeEmitter.prototype, EventEmitter.prototype); Object.assign(FakeEmitter, EventEmitter); return new FakeEmitter(); @@ -118,6 +118,7 @@ for (let create of waysOfCreating) { var called = false; (myEmitter as EventEmitter).once("event", function () { called = true; + // @ts-ignore expect(this).toBe(myEmitter); }); var firstEvents = myEmitter._events; @@ -153,8 +154,8 @@ test("EventEmitter GCs", async () => { Object.setPrototypeOf(EventEmitterSubclass.prototype, EventEmitter.prototype); Object.setPrototypeOf(EventEmitterSubclass, EventEmitter); - - var myEmitter = new (EventEmitterSubclass as any)(); + // @ts-ignore + var myEmitter = new EventEmitterSubclass(); myEmitter.on("foo", () => {}); myEmitter.emit("foo"); })(); diff --git a/test/js/node/fs/fs.test.ts b/test/js/node/fs/fs.test.ts index 48abef6cb..4636d0d4b 100644 --- a/test/js/node/fs/fs.test.ts +++ b/test/js/node/fs/fs.test.ts @@ -1,5 +1,5 @@ -import { beforeEach, describe, expect, it } from "bun:test"; -import { gc, gcTick } from "harness"; +import { describe, expect, it } from "bun:test"; +import { gc } from "harness"; import fs, { closeSync, existsSync, @@ -41,7 +41,7 @@ if (!import.meta.dir) { import.meta.dir = "."; } -function mkdirForce(path) { +function mkdirForce(path: string) { if (!existsSync(path)) mkdirSync(path, { recursive: true }); } @@ -368,7 +368,7 @@ describe("writeFileSync", () => { }); }); -function triggerDOMJIT(target, fn, result) { +function triggerDOMJIT(target: fs.Stats, fn: (..._: any[]) => any, result: any) { for (let i = 0; i < 9999; i++) { if (fn.apply(target) !== result) { throw new Error("DOMJIT failed"); diff --git a/test/js/node/harness.ts b/test/js/node/harness.ts index 9e847c649..9cea1b781 100644 --- a/test/js/node/harness.ts +++ b/test/js/node/harness.ts @@ -1,3 +1,4 @@ +import { AnyFunction } from "bun"; import { gcTick, hideFromStackTrace } from "harness"; import assertNode from "node:assert"; @@ -44,10 +45,20 @@ export function createTest(path: string) { expect(true).toBe(true); }; + interface NodeAssert { + (args: any): void; + strictEqual: typeof strictEqual; + deepStrictEqual: typeof deepStrictEqual; + notStrictEqual: typeof notStrictEqual; + throws: typeof throws; + ok: typeof ok; + ifError: typeof ifError; + match: typeof match; + } const assert = function (...args: any[]) { // @ts-ignore assertNode(...args); - }; + } as NodeAssert; hideFromStackTrace(strictEqual); hideFromStackTrace(notStrictEqual); @@ -87,8 +98,8 @@ export function createTest(path: string) { // }); // TODO: Implement this to be exact only - function mustCall(fn?: (...args) => any, exact?: number) { - return mustCallAtLeast(fn, exact); + function mustCall(fn?: (...args: any[]) => any, exact?: number) { + return mustCallAtLeast(fn!, exact!); } function closeTimers() { @@ -114,11 +125,12 @@ export function createTest(path: string) { }, exact); } - function mustCallAtLeast(fn, minimum) { + function mustCallAtLeast(fn: AnyFunction, minimum: number) { return _mustCallInner(fn, minimum, "minimum"); } - function _mustCallInner(fn, criteria = 1, field) { + function _mustCallInner(fn: AnyFunction, criteria = 1, field: string) { + // @ts-ignore if (process._exiting) throw new Error("Cannot use common.mustCall*() in process exit handler"); if (typeof fn === "number") { criteria = fn; @@ -134,7 +146,7 @@ export function createTest(path: string) { // mustCallChecks.push(context); const done = createDone(); - const _return = (...args) => { + const _return = (...args: any[]) => { try { // @ts-ignore const result = fn(...args); diff --git a/test/js/node/http/node-http.fixme.ts b/test/js/node/http/node-http.fixme.ts index 6b01f66c3..30bfab8f9 100644 --- a/test/js/node/http/node-http.fixme.ts +++ b/test/js/node/http/node-http.fixme.ts @@ -1,8 +1,9 @@ +// @ts-nocheck import { createServer, request, get, Agent, globalAgent, Server } from "node:http"; import { createTest } from "node-harness"; const { describe, expect, it, beforeAll, afterAll, createDoneDotAll } = createTest(import.meta.path); -function listen(server: any): Promise<URL> { +function listen(server: Server): Promise<URL> { return new Promise((resolve, reject) => { server.listen({ port: 0 }, (err, hostname, port) => { if (err) { diff --git a/test/js/node/net/node-net-server.test.ts b/test/js/node/net/node-net-server.test.ts index e8b5234e6..86887b437 100644 --- a/test/js/node/net/node-net-server.test.ts +++ b/test/js/node/net/node-net-server.test.ts @@ -185,7 +185,7 @@ describe("net.createServer listen", () => { it("should receive data", done => { const { mustCall, mustNotCall } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; const onData = mustCall(data => { clearTimeout(timeout); @@ -195,7 +195,7 @@ it("should receive data", done => { done(); }); - const server = createServer(socket => { + const server = createServer((socket: any) => { socket.on("data", onData); }); @@ -232,7 +232,7 @@ it("should receive data", done => { it("should call end", done => { const { mustCall, mustNotCall } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; const onEnd = mustCall(() => { clearTimeout(timeout); @@ -240,7 +240,7 @@ it("should call end", done => { done(); }); - const server = createServer(socket => { + const server = createServer((socket: any) => { socket.on("end", onEnd); socket.end(); }); @@ -286,7 +286,7 @@ it("should call close", done => { it("should call connection and drop", done => { const { mustCall, mustNotCall } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; const server = createServer(); let maxClients = 2; server.maxConnections = maxClients - 1; @@ -350,7 +350,7 @@ it("should call connection and drop", done => { it("should call listening", done => { const { mustCall, mustNotCall } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; const server = createServer(); let maxClients = 2; server.maxConnections = maxClients - 1; @@ -381,7 +381,7 @@ it("should call listening", done => { it("should call error", done => { const { mustCall, mustNotCall, closeTimers } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; const server = createServer(); let maxClients = 2; server.maxConnections = maxClients - 1; @@ -415,7 +415,7 @@ it("should call abort with signal", done => { const { mustCall, mustNotCall, closeTimers } = createCallCheckCtx(done); const controller = new AbortController(); - let timeout; + let timeout: number | Timer; const server = createServer(); let maxClients = 2; server.maxConnections = maxClients - 1; @@ -446,9 +446,9 @@ it("should call abort with signal", done => { it("should echo data", done => { const { mustCall, mustNotCall, closeTimers } = createCallCheckCtx(done); - let timeout; + let timeout: number | Timer; - const server = createServer(socket => { + const server = createServer((socket: any) => { socket.pipe(socket); }); diff --git a/test/js/node/net/node-net.test.ts b/test/js/node/net/node-net.test.ts index 02348487f..cccada5c0 100644 --- a/test/js/node/net/node-net.test.ts +++ b/test/js/node/net/node-net.test.ts @@ -1,3 +1,4 @@ +import { ServerWebSocket, TCPSocket, Socket as _BunSocket, TCPSocketListener } from "bun"; import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "bun:test"; import { connect, isIP, isIPv4, isIPv6, Socket } from "net"; import { realpathSync, mkdtempSync } from "fs"; @@ -38,9 +39,9 @@ describe("net.Socket read", () => { ["Hello!", "short message"], ]) { describe(label, () => { - function runWithServer(cb, unix_domain_path) { - return done => { - function drain(socket) { + function runWithServer(cb: (..._: any[]) => void, unix_domain_path?: any) { + return (done: (_: any) => void) => { + function drain(socket: _BunSocket<{ message: string }>) { const message = socket.data.message; const written = socket.write(message); if (written < message.length) { @@ -50,44 +51,42 @@ describe("net.Socket read", () => { } } - var server = Bun.listen( - unix_domain_path - ? { - unix: join(unix_domain_path, `${unix_servers++}.sock`), - socket: { - open(socket) { - socket.data.message = message; - drain(socket); - }, - drain, - error(socket, err) { - done(err); - }, + var server = unix_domain_path + ? Bun.listen({ + unix: join(unix_domain_path, `${unix_servers++}.sock`), + socket: { + open(socket) { + socket.data.message = message; + drain(socket); }, - data: { - message: "", + drain, + error(socket, err) { + done(err); }, - } - : { - hostname: "localhost", - port: 0, - socket: { - open(socket) { - socket.data.message = message; - drain(socket); - }, - drain, - error(socket, err) { - done(err); - }, + }, + data: { + message: "", + }, + }) + : Bun.listen({ + hostname: "localhost", + port: 0, + socket: { + open(socket) { + socket.data.message = message; + drain(socket); }, - data: { - message: "", + drain, + error(socket, err) { + done(err); }, }, - ); + data: { + message: "", + }, + }); - function onDone(err) { + function onDone(err: any) { server.stop(); done(err); } @@ -237,11 +236,11 @@ describe("net.Socket write", () => { const message = "Hello World!".repeat(1024); let port = 53213; - function runWithServer(cb) { - return done => { - let server; + function runWithServer(cb: (..._: any[]) => void) { + return (done: (_?: any) => void) => { + let server: TCPSocketListener<unknown>; - function close(socket) { + function close(socket: _BunSocket<Buffer[]>) { expect(Buffer.concat(socket.data).toString("utf8")).toBe(message); done(); } @@ -273,7 +272,7 @@ describe("net.Socket write", () => { data: [] as Buffer[], }); - function onDone(err) { + function onDone(err: any) { server.stop(); done(err); } @@ -334,6 +333,7 @@ describe("net.Socket write", () => { it("should handle connection error", done => { var data = {}; + // @ts-ignore connect(55555, () => { done(new Error("Should not have connected")); }).on("error", error => { diff --git a/test/js/node/readline/readline.node.test.ts b/test/js/node/readline/readline.node.test.ts index a1077a799..a21e426b0 100644 --- a/test/js/node/readline/readline.node.test.ts +++ b/test/js/node/readline/readline.node.test.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import readline from "node:readline"; import { Writable, PassThrough } from "node:stream"; import { EventEmitter } from "node:events"; @@ -7,6 +8,7 @@ const { beforeEach, describe, it, createDoneDotAll, createCallCheckCtx, assert } var { CSI, utils: { getStringWidth, stripVTControlCharacters }, + // @ts-ignore } = readline[Symbol.for("__BUN_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__")]; // ---------------------------------------------------------------------------- diff --git a/test/js/node/readline/readline_promises.node.test.ts b/test/js/node/readline/readline_promises.node.test.ts index 8a4ac014f..a6a464225 100644 --- a/test/js/node/readline/readline_promises.node.test.ts +++ b/test/js/node/readline/readline_promises.node.test.ts @@ -11,7 +11,7 @@ class FakeInput extends EventEmitter { output = ""; resume() {} pause() {} - write(data) { + write(data: any) { this.output += data; } end() {} @@ -30,6 +30,7 @@ describe("readline/promises.createInterface()", () => { const { mustCall, mustNotCall } = createCallCheckCtx(createDone()); const fi = new FakeInput(); + // @ts-ignore const rli = new readlinePromises.Interface({ input: fi, output: fi, diff --git a/test/js/node/stream/bufferlist.test.ts b/test/js/node/stream/bufferlist.test.ts index b8a5443ea..8ab147d7e 100644 --- a/test/js/node/stream/bufferlist.test.ts +++ b/test/js/node/stream/bufferlist.test.ts @@ -1,15 +1,16 @@ import { Readable } from "stream"; import { it, expect } from "bun:test"; -function makeUint8Array(str) { +function makeUint8Array(str: string) { return new Uint8Array( - [].map.call(str, function (ch) { + [].map.call(str, function (ch: string) { return ch.charCodeAt(0); - }), + }) as number[], ); } it("should work with .clear()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push({})).toBeUndefined(); @@ -21,6 +22,7 @@ it("should work with .clear()", () => { }); it("should work with .concat()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push(makeUint8Array("foo"))).toBeUndefined(); @@ -32,6 +34,7 @@ it("should work with .concat()", () => { }); it("should fail on .concat() with invalid items", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push("foo")).toBeUndefined(); @@ -41,6 +44,7 @@ it("should fail on .concat() with invalid items", () => { }); it("should fail on .concat() buffer overflow", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push(makeUint8Array("foo"))).toBeUndefined(); @@ -56,6 +60,7 @@ it("should fail on .concat() buffer overflow", () => { }); it("should work with .consume() on strings", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.consume(42, true)).toBe(""); @@ -74,6 +79,7 @@ it("should work with .consume() on strings", () => { }); it("should work with .consume() on buffers", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.consume(42, false)).toEqual(new Uint8Array()); @@ -94,6 +100,7 @@ it("should work with .consume() on buffers", () => { }); it("should fail on .consume() with invalid items", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push("foo")).toBeUndefined(); @@ -114,6 +121,7 @@ it("should fail on .consume() with invalid items", () => { }); it("should work with .first()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.first()).toBeUndefined(); @@ -124,6 +132,7 @@ it("should work with .first()", () => { }); it("should work with .join()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push(42)).toBeUndefined(); @@ -137,6 +146,7 @@ it("should work with .join()", () => { }); it("should work with .push()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); const item1 = {}; @@ -152,6 +162,7 @@ it("should work with .push()", () => { }); it("should work with .shift()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.shift()).toBeUndefined(); @@ -163,6 +174,7 @@ it("should work with .shift()", () => { }); it("should work with .unshift()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); const item1 = {}; @@ -183,6 +195,7 @@ it("should work with .unshift()", () => { }); it("should work with partial .consume() followed by .first()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push("foo")).toBeUndefined(); @@ -195,6 +208,7 @@ it("should work with partial .consume() followed by .first()", () => { }); it("should work with partial .consume() followed by .shift()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push(makeUint8Array("foo"))).toBeUndefined(); @@ -207,6 +221,7 @@ it("should work with partial .consume() followed by .shift()", () => { }); it("should work with partial .consume() followed by .unshift()", () => { + // @ts-ignore const list = new Readable().readableBuffer; expect(list.length).toBe(0); expect(list.push(makeUint8Array("πππ"))).toBeUndefined(); diff --git a/test/js/node/stream/node-stream-uint8array.test.ts b/test/js/node/stream/node-stream-uint8array.test.ts index ec2e95d34..fd2759224 100644 --- a/test/js/node/stream/node-stream-uint8array.test.ts +++ b/test/js/node/stream/node-stream-uint8array.test.ts @@ -1,16 +1,17 @@ import { beforeEach, describe, expect, it } from "bun:test"; -import { Readable, Writable } from "stream"; +import { Readable, Writable, WritableOptions } from "stream"; const ABC = new Uint8Array([0x41, 0x42, 0x43]); const DEF = new Uint8Array([0x44, 0x45, 0x46]); const GHI = new Uint8Array([0x47, 0x48, 0x49]); describe("Writable", () => { - let called; + let called: number[]; - function logCall(fn, id) { + function logCall(fn: WritableOptions["write"], id: number) { return function () { called[id] = (called[id] || 0) + 1; + // @ts-ignore return fn.apply(this, arguments); }; } @@ -56,7 +57,7 @@ describe("Writable", () => { }); it("should handle multiple writes carried out via writev()", () => { - let callback; + let callback!: () => void; const writable = new Writable({ write: logCall((chunk, encoding, cb) => { diff --git a/test/js/third_party/body-parser/express-body-parser-test.test.ts b/test/js/third_party/body-parser/express-body-parser-test.test.ts index 1f95b318e..b9cd6bbac 100644 --- a/test/js/third_party/body-parser/express-body-parser-test.test.ts +++ b/test/js/third_party/body-parser/express-body-parser-test.test.ts @@ -1,3 +1,6 @@ +// @ts-nocheck +// can't use @types/express or @types/body-parser because they +// depend on @types/node which conflicts with bun-types import { test, expect } from "bun:test"; import express, { Application, Request, Response } from "express"; import { json } from "body-parser"; diff --git a/test/js/third_party/napi_create_external/napi-create-external.test.ts b/test/js/third_party/napi_create_external/napi-create-external.test.ts index c3fe5ad65..47025e100 100644 --- a/test/js/third_party/napi_create_external/napi-create-external.test.ts +++ b/test/js/third_party/napi_create_external/napi-create-external.test.ts @@ -1,9 +1,10 @@ +// @ts-nocheck import { test, it, describe, expect } from "bun:test"; import { withoutAggressiveGC } from "harness"; import * as _ from "lodash"; function rebase(str, inBase, outBase) { - const mapBase = b => (b === 2 ? 32 : b === 16 ? 8 : null); + const mapBase = (b: number) => (b === 2 ? 32 : b === 16 ? 8 : null); const stride = mapBase(inBase); const pad = mapBase(outBase); if (!stride) throw new Error(`Bad inBase ${inBase}`); diff --git a/test/js/web/crypto/web-crypto.test.ts b/test/js/web/crypto/web-crypto.test.ts index 250282b96..b8155c3ba 100644 --- a/test/js/web/crypto/web-crypto.test.ts +++ b/test/js/web/crypto/web-crypto.test.ts @@ -37,7 +37,7 @@ describe("Web Crypto", () => { }); it("should verify and sign", async () => { - async function importKey(secret) { + async function importKey(secret: string) { return await crypto.subtle.importKey( "raw", new TextEncoder().encode(secret), @@ -47,7 +47,7 @@ describe("Web Crypto", () => { ); } - async function signResponse(message, secret) { + async function signResponse(message: string, secret: string) { const key = await importKey(secret); const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(message)); @@ -55,7 +55,7 @@ describe("Web Crypto", () => { return btoa(String.fromCharCode(...new Uint8Array(signature))); } - async function verifySignature(message, signature, secret) { + async function verifySignature(message: string, signature: string, secret: string) { const key = await importKey(secret); // Convert Base64 to Uint8Array diff --git a/test/js/web/fetch/body.test.ts b/test/js/web/fetch/body.test.ts index fa3d4e53b..2b9b3e11d 100644 --- a/test/js/web/fetch/body.test.ts +++ b/test/js/web/fetch/body.test.ts @@ -245,11 +245,9 @@ for (const { body, fn } of bodyTypes) { }); test(body.name, async () => { for (const { string, buffer } of utf8) { - // @ts-expect-error expect(() => { fn(buffer); }).not.toThrow(); - // @ts-expect-error expect(await fn(buffer).text()).toBe(string); } }); diff --git a/test/js/web/fetch/fetch-gzip.test.ts b/test/js/web/fetch/fetch-gzip.test.ts index 91ea8de9f..076b5845b 100644 --- a/test/js/web/fetch/fetch-gzip.test.ts +++ b/test/js/web/fetch/fetch-gzip.test.ts @@ -1,7 +1,6 @@ -import { concatArrayBuffers } from "bun"; -import { it, describe, expect } from "bun:test"; -import fs from "fs"; -import { gc, gcTick } from "harness"; +import { concatArrayBuffers, Socket, TCPSocketListener } from "bun"; +import { it, expect } from "bun:test"; +import { gcTick } from "harness"; it("fetch() with a buffered gzip response works (one chunk)", async () => { var server = Bun.serve({ @@ -122,9 +121,15 @@ it("fetch() with a gzip response works (one chunk, streamed, with a delay", asyn server.stop(); }); +const arg = Bun.listen({ + hostname: "asdf", + port: 1234, + socket: {}, +}); + it("fetch() with a gzip response works (multiple chunks, TCP server", async done => { const compressed = await Bun.file(import.meta.dir + "/fixture.html.gz").arrayBuffer(); - var socketToClose; + var socketToClose!: Socket; const server = Bun.listen({ port: 0, hostname: "0.0.0.0", @@ -134,7 +139,7 @@ it("fetch() with a gzip response works (multiple chunks, TCP server", async done var corked: any[] = []; var cork = true; - async function write(chunk) { + async function write(chunk: any) { await new Promise<void>((resolve, reject) => { if (cork) { corked.push(chunk); diff --git a/test/js/web/fetch/fetch.test.ts b/test/js/web/fetch/fetch.test.ts index 1f2345f85..f723761a7 100644 --- a/test/js/web/fetch/fetch.test.ts +++ b/test/js/web/fetch/fetch.test.ts @@ -1,4 +1,4 @@ -import { serve, sleep } from "bun"; +import { AnyFunction, serve, ServeOptions, Server, sleep } from "bun"; import { afterAll, afterEach, beforeAll, describe, expect, it, beforeEach } from "bun:test"; import { chmodSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "fs"; import { mkfifo } from "mkfifo"; @@ -10,8 +10,8 @@ const tmp_dir = mkdtempSync(join(realpathSync(tmpdir()), "fetch.test")); const fixture = readFileSync(join(import.meta.dir, "fetch.js.txt"), "utf8"); -let server; -function startServer({ fetch, ...options }) { +let server: Server; +function startServer({ fetch, ...options }: ServeOptions) { server = serve({ ...options, fetch, @@ -38,7 +38,7 @@ describe("AbortSignal", () => { return new Response("Hello"); } if (request.url.endsWith("/stream")) { - const reader = request.body.getReader(); + const reader = request.body!.getReader(); const body = new ReadableStream({ async pull(controller) { if (!reader) controller.close(); @@ -113,11 +113,11 @@ describe("AbortSignal", () => { const controller = new AbortController(); const signal = controller.signal; signal.addEventListener("abort", ev => { - const target = ev.currentTarget; + const target = ev.currentTarget!; expect(target).toBeDefined(); expect(target.aborted).toBe(true); expect(target.reason).toBeDefined(); - expect(target.reason.name).toBe("AbortError"); + expect(target.reason!.name).toBe("AbortError"); }); expect(async () => { @@ -280,11 +280,11 @@ describe("fetch", () => { "http://example.com", new URL("https://example.com"), new Request({ url: "https://example.com" }), - { toString: () => "https://example.com" }, + { toString: () => "https://example.com" } as string, ]; for (let url of urls) { gc(); - let name; + let name: string; if (url instanceof URL) { name = "URL: " + url; } else if (url instanceof Request) { @@ -292,7 +292,7 @@ describe("fetch", () => { } else if (url.hasOwnProperty("toString")) { name = "Object: " + url.toString(); } else { - name = url; + name = url as string; } it(name, async () => { gc(); @@ -347,7 +347,7 @@ describe("fetch", () => { fetch(req) { return new Response(req.body); }, - host: "localhost", + hostname: "localhost", }); // POST with body @@ -388,7 +388,7 @@ it("website with tlsextname", async () => { await fetch("https://bun.sh", { method: "HEAD" }); }); -function testBlobInterface(blobbyConstructor, hasBlobFn?) { +function testBlobInterface(blobbyConstructor: { (..._: any[]): any }, hasBlobFn?: boolean) { for (let withGC of [false, true]) { for (let jsonObject of [ { hello: true }, @@ -534,7 +534,7 @@ describe("Bun.file", () => { let count = 0; testBlobInterface(data => { const blob = new Blob([data]); - const buffer = Bun.peek(blob.arrayBuffer()); + const buffer = Bun.peek(blob.arrayBuffer()) as ArrayBuffer; const path = join(tmp_dir, `tmp-${count++}.bytes`); writeFileSync(path, buffer); const file = Bun.file(path); @@ -549,8 +549,8 @@ describe("Bun.file", () => { expect(size).toBe(Infinity); }); - function forEachMethod(fn, skip?) { - const method = ["arrayBuffer", "text", "json"]; + const method = ["arrayBuffer", "text", "json"] as const; + function forEachMethod(fn: (m: (typeof method)[number]) => any, skip?: AnyFunction) { for (const m of method) { (skip ? it.skip : it)(m, fn(m)); } @@ -643,7 +643,7 @@ describe("Blob", () => { "π π π π π π
π π€£ π₯² βΊοΈ π π π π π π π π₯° π π π π π π π π π€ͺ π€¨ π§ π€ π π₯Έ π€© π₯³", ), ], - ]; + ] as any[]; var expected = [ "123456", @@ -721,7 +721,7 @@ describe("Blob", () => { const input = Constructor === Blob ? [data] : Constructor === Request ? { body: data, url: "http://example.com" } : data; if (withGC) gc(); - const blob = new Constructor(input); + const blob = new Constructor(input as any); if (withGC) gc(); const out = await blob.arrayBuffer(); if (withGC) gc(); @@ -1101,12 +1101,14 @@ it("body nullable", async () => { }); it("Request({}) throws", async () => { + // @ts-expect-error expect(() => new Request({})).toThrow(); }); it("Request({toString() { throw 'wat'; } }) throws", async () => { expect( () => + // @ts-expect-error new Request({ toString() { throw "wat"; @@ -1123,6 +1125,5 @@ it("should not be able to parse json from empty body", () => { it("#874", () => { expect(new Request(new Request("https://example.com"), {}).url).toBe("https://example.com"); expect(new Request(new Request("https://example.com")).url).toBe("https://example.com"); - // @ts-expect-error expect(new Request({ url: "https://example.com" }).url).toBe("https://example.com"); }); diff --git a/test/js/web/html/FormData.test.ts b/test/js/web/html/FormData.test.ts index edefe8a53..af2871b10 100644 --- a/test/js/web/html/FormData.test.ts +++ b/test/js/web/html/FormData.test.ts @@ -1,7 +1,9 @@ import { afterAll, beforeAll, describe, expect, it, test } from "bun:test"; import fs, { chmodSync, unlinkSync } from "fs"; +import { gc, withoutAggressiveGC } from "harness"; import { mkfifo } from "mkfifo"; -import { gc, withoutAggressiveGC } from "../../gc"; + +gc; describe("FormData", () => { it("should be able to append a string", () => { @@ -14,14 +16,14 @@ describe("FormData", () => { it("should be able to append a Blob", async () => { const formData = new FormData(); formData.append("foo", new Blob(["bar"])); - expect(await formData.get("foo")!.text()).toBe("bar"); + expect(await ((await formData.get("foo")) as Blob)!.text()).toBe("bar"); expect(formData.getAll("foo")[0] instanceof Blob).toBe(true); }); it("should be able to set a Blob", async () => { const formData = new FormData(); formData.set("foo", new Blob(["bar"])); - expect(await formData.get("foo")!.text()).toBe("bar"); + expect(await ((await formData.get("foo")) as Blob).text()).toBe("bar"); expect(formData.getAll("foo")[0] instanceof Blob).toBe(true); }); @@ -135,8 +137,8 @@ describe("FormData", () => { C === Response ? new Response(body, { headers }) : new Request({ headers, body, url: "http://hello.com" }); const formData = await response.formData(); expect(formData instanceof FormData).toBe(true); - const entry = {}; - const expected = Object.assign({}, expected_); + const entry: { [k: string]: any } = {}; + const expected: { [k: string]: any } = Object.assign({}, expected_); for (const key of formData.keys()) { const values = formData.getAll(key); @@ -180,7 +182,7 @@ describe("FormData", () => { const b = bValues[i]; if (a instanceof Blob) { expect(b instanceof Blob).toBe(true); - expect(await a.text()).toBe(await b.text()); + expect(await a.text()).toBe(await (b as Blob).text()); } else { expect(a).toBe(b); } @@ -200,7 +202,7 @@ describe("FormData", () => { const b = bValues[i]; if (c instanceof Blob) { expect(b instanceof Blob).toBe(true); - expect(await c.text()).toBe(await b.text()); + expect(await c.text()).toBe(await (b as Blob).text()); } else { expect(c).toBe(b); } @@ -219,7 +221,7 @@ describe("FormData", () => { try { await response.formData(); throw "should have thrown"; - } catch (e) { + } catch (e: any) { expect(typeof e.message).toBe("string"); } }); @@ -233,7 +235,7 @@ describe("FormData", () => { try { await response.formData(); throw "should have thrown"; - } catch (e) { + } catch (e: any) { expect(typeof e.message).toBe("string"); } }); @@ -247,7 +249,7 @@ describe("FormData", () => { try { await response.formData(); throw "should have thrown"; - } catch (e) { + } catch (e: any) { expect(typeof e.message).toBe("string"); } }); diff --git a/test/mkfifo.ts b/test/mkfifo.ts index 48471cbf5..1fd045723 100644 --- a/test/mkfifo.ts +++ b/test/mkfifo.ts @@ -1,6 +1,6 @@ import { dlopen, ptr } from "bun:ffi"; -var lazyMkfifo; +var lazyMkfifo: any; export function mkfifo(path: string, permissions: number = 0o666): void { if (!lazyMkfifo) { const suffix = process.platform === "darwin" ? "dylib" : "so.6"; diff --git a/test/package.json b/test/package.json index e886f613c..5688df194 100644 --- a/test/package.json +++ b/test/package.json @@ -1,10 +1,11 @@ { - "private": true, "name": "test", "type": "module", "devDependencies": {}, "dependencies": { "@swc/core": "^1.3.38", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", "bktree-fast": "^0.0.7", "body-parser": "^1.20.2", "esbuild": "^0.17.11", @@ -12,6 +13,11 @@ "iconv-lite": "^0.6.3", "lodash": "^4.17.21", "svelte": "^3.55.1", + "typescript": "^5.0.2", "undici": "^5.20.0" + }, + "private": true, + "scripts": { + "typecheck": "tsc --noEmit" } } diff --git a/test/tsconfig.json b/test/tsconfig.json index d6be02bff..e32033f8c 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,10 +1,16 @@ { + "include": [ + ".", + "../packages/bun-types/index.d.ts" + ], "compilerOptions": { "noEmit": true, - "lib": ["ESNext"], + "lib": [ + "ESNext" + ], "module": "ESNext", "target": "ESNext", - "moduleResolution": "nodenext", + "moduleResolution": "bundler", "strict": true, "downlevelIteration": true, "skipLibCheck": true, @@ -13,15 +19,25 @@ "forceConsistentCasingInFileNames": true, "allowJs": true, "resolveJsonModule": true, - "types": ["../packages/bun-types"], "baseUrl": ".", "paths": { - "harness": ["harness.ts"], - "mkfifo": ["mkfifo.ts"], - "node-harness": ["js/node/harness.ts"], - "deno:harness": ["js/deno/harness.ts"], - "foo/bar": ["js/bun/resolve/baz.js"], - "@faasjs/*": ["js/bun/resolve/*.js"] + "harness": [ + "harness.ts" + ], + "mkfifo": [ + "mkfifo.ts" + ], + "node-harness": [ + "js/node/harness.ts" + ], + "deno:harness": [ + "js/deno/harness.ts" + ] } - } + }, + "exclude": [ + "fixtures", + "snapshots", + "js/deno" + ] } diff --git a/tsconfig.json b/tsconfig.json index 272fd944a..77ee0a0fd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,22 +8,20 @@ }, "include": [ ".", - "**/*.d.ts" + "packages/bun-types/index.d.ts" ], "exclude": [ "src/test", "packages", "bench", - "examples/react-fast-refresh-test", - "examples/macros", + "examples/*/*", + "test", "src/deps", "bun-webkit", // JavaScriptCore builtins use a non-standard "@" symbol to indicate a private identifier which no other tool supports "src/bun.js/builtins", "src/bun.js/WebKit", "src/api/demo", - "test/snapshots", - "test/snapshots-no-hmr", - "node_modules" + "node_modules", ] } |