diff options
-rw-r--r-- | packages/bun-types/globals.d.ts | 16 | ||||
-rw-r--r-- | test/js/web/abort/abort-signal-timeout.test.js | 12 | ||||
-rw-r--r-- | test/js/web/abort/abort.test.ts | 173 | ||||
-rw-r--r-- | test/package.json | 4 | ||||
-rw-r--r-- | test/tsconfig.json | 2 |
5 files changed, 184 insertions, 23 deletions
diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index 59c7f7971..6bb02e0c2 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -1965,6 +1965,10 @@ 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, @@ -1986,7 +1990,12 @@ interface AbortSignal extends EventTarget { listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions, ): void; +} +declare var AbortSignal: { + prototype: AbortSignal; + new (): AbortSignal; + abort(reason?: any): AbortSignal; /** * Create an AbortSignal which times out after milliseconds * @@ -2003,13 +2012,6 @@ interface AbortSignal extends EventTarget { * ``` */ timeout(milliseconds: number): AbortSignal; -} - -declare var AbortSignal: { - prototype: AbortSignal; - new (): AbortSignal; - abort(reason?: any): AbortSignal; - timeout(milliseconds: number): AbortSignal; }; // type AlgorithmIdentifier = Algorithm | string; diff --git a/test/js/web/abort/abort-signal-timeout.test.js b/test/js/web/abort/abort-signal-timeout.test.js deleted file mode 100644 index 7d741b2ad..000000000 --- a/test/js/web/abort/abort-signal-timeout.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { expect, test } from "bun:test"; - -test.skip("AbortSignal.timeout", done => { - const abort = AbortSignal.timeout(10); - abort.addEventListener("abort", event => { - done(); - }); - - // AbortSignal.timeout doesn't keep the event loop / process alive - // so we set a no-op timeout - setTimeout(() => {}, 11); -}); diff --git a/test/js/web/abort/abort.test.ts b/test/js/web/abort/abort.test.ts new file mode 100644 index 000000000..c72f7cb5a --- /dev/null +++ b/test/js/web/abort/abort.test.ts @@ -0,0 +1,173 @@ +import { describe, test, expect } from "bun:test"; + +describe("AbortSignal", () => { + test("constructor", () => { + expect(() => new AbortSignal()).toThrow(TypeError); + }); + describe("abort()", () => { + const reasons = [ + { + label: "undefined", + reason: undefined, + }, + { + label: "null", + reason: null, + }, + { + label: "string", + reason: "Aborted!", + }, + { + label: "Error", + reason: new Error("Aborted!"), + }, + { + label: "object", + reason: { + ok: false, + error: "Aborted!", + }, + }, + ]; + for (const { label, reason } of reasons) { + test(label, () => { + const signal = AbortSignal.abort(reason); + expect(signal instanceof AbortSignal).toBe(true); + expect(signal).toHaveProperty("aborted", true); + if (reason === undefined) { + expect(signal).toHaveProperty("reason"); + expect(signal.reason instanceof DOMException).toBe(true); + } else { + expect(signal).toHaveProperty("reason", reason); + } + }); + } + }); + describe("timeout()", () => { + const valid = [ + { + label: "0", + timeout: 0, + }, + { + label: "1", + timeout: 1, + }, + { + label: "Number.MAX_SAFE_INTEGER", + timeout: Number.MAX_SAFE_INTEGER, + }, + ]; + for (const { label, timeout } of valid) { + test(label, () => { + const signal = AbortSignal.timeout(timeout); + expect(signal instanceof AbortSignal).toBe(true); + expect(signal instanceof EventTarget).toBe(true); + expect(signal).toHaveProperty("aborted", false); + expect(signal).toHaveProperty("reason", undefined); + }); + } + const invalid = [ + { + label: "-1", + timeout: -1, + }, + { + label: "NaN", + timeout: NaN, + }, + { + label: "Infinity", + timeout: Infinity, + }, + { + label: "Number.MAX_VALUE", + timeout: Number.MAX_VALUE, + }, + ]; + for (const { label, timeout } of invalid) { + test(label, () => { + expect(() => AbortSignal.timeout(timeout)).toThrow(TypeError); + }); + } + // FIXME: test runner hangs when this is enabled + test.skip("timeout works", done => { + const abort = AbortSignal.timeout(1); + abort.addEventListener("abort", event => { + done(); + }); + // AbortSignal.timeout doesn't keep the event loop / process alive + // so we set a no-op timeout + setTimeout(() => {}, 10); + }); + }); + describe("prototype", () => { + test("aborted", () => { + expect(AbortSignal.abort()).toHaveProperty("aborted", true); + expect(AbortSignal.timeout(0)).toHaveProperty("aborted", false); + }); + test("reason", () => { + expect(AbortSignal.abort()).toHaveProperty("reason"); + expect(AbortSignal.timeout(0)).toHaveProperty("reason"); + }); + test("onabort", () => { + const signal = AbortSignal.timeout(0); + expect(signal.onabort).toBeNull(); + const onabort = (event: Event) => { + expect(event instanceof Event).toBe(true); + }; + expect(() => (signal.onabort = onabort)).not.toThrow(); + expect(signal.onabort).toStrictEqual(onabort); + }); + }); +}); + +describe("AbortController", () => { + test("contructor", () => { + expect(() => new AbortController()).not.toThrow(); + }); + describe("prototype", () => { + test("signal", () => { + const controller = new AbortController(); + expect(controller).toHaveProperty("signal"); + expect(controller.signal instanceof AbortSignal).toBe(true); + }); + describe("abort()", () => { + const reasons = [ + { + label: "undefined", + reason: undefined, + }, + { + label: "string", + reason: "Aborted", + }, + { + label: "Error", + reason: new Error("Aborted"), + }, + ]; + for (const { label, reason } of reasons) { + test(label, () => { + const controller = new AbortController(); + let event: Event | undefined; + expect(() => { + controller.signal.onabort = data => { + event = data; + }; + }).not.toThrow(); + expect(controller).toHaveProperty("abort"); + expect(() => controller.abort()).not.toThrow(); + expect(event instanceof Event).toBe(true); + expect(controller.signal.aborted).toBe(true); + if (reason === undefined) { + expect(controller.signal.reason instanceof DOMException).toBe(true); + } else { + expect(controller.signal.reason).toStrictEqual(reason); + } + }); + } + }); + }); +}); diff --git a/test/package.json b/test/package.json index bffbfee57..bb3245788 100644 --- a/test/package.json +++ b/test/package.json @@ -2,9 +2,7 @@ "private": true, "name": "test", "type": "module", - "devDependencies": { - "bun-types": "canary" - }, + "devDependencies": {}, "dependencies": { "@swc/core": "^1.3.38", "bktree-fast": "^0.0.7", diff --git a/test/tsconfig.json b/test/tsconfig.json index 12ad19dc7..2ce6a4d4d 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -13,7 +13,7 @@ "forceConsistentCasingInFileNames": true, "allowJs": true, "resolveJsonModule": true, - "types": ["bun-types"], + "types": ["../packages/bun-types"], "baseUrl": ".", "paths": { "harness": ["harness.ts"], |