aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/bun-types/globals.d.ts16
-rw-r--r--test/js/web/abort/abort-signal-timeout.test.js12
-rw-r--r--test/js/web/abort/abort.test.ts173
-rw-r--r--test/package.json4
-rw-r--r--test/tsconfig.json2
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"],