diff options
Diffstat (limited to 'test/js/web/web-globals.test.js')
-rw-r--r-- | test/js/web/web-globals.test.js | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/test/js/web/web-globals.test.js b/test/js/web/web-globals.test.js new file mode 100644 index 000000000..b7a243190 --- /dev/null +++ b/test/js/web/web-globals.test.js @@ -0,0 +1,156 @@ +import { unsafe } from "bun"; +import { expect, it, test } from "bun:test"; +import { withoutAggressiveGC } from "harness"; + +test("exists", () => { + expect(typeof URL !== "undefined").toBe(true); + expect(typeof URLSearchParams !== "undefined").toBe(true); + expect(typeof DOMException !== "undefined").toBe(true); + expect(typeof Event !== "undefined").toBe(true); + expect(typeof EventTarget !== "undefined").toBe(true); + expect(typeof AbortController !== "undefined").toBe(true); + expect(typeof AbortSignal !== "undefined").toBe(true); + expect(typeof CustomEvent !== "undefined").toBe(true); + expect(typeof Headers !== "undefined").toBe(true); + expect(typeof ErrorEvent !== "undefined").toBe(true); + expect(typeof CloseEvent !== "undefined").toBe(true); + expect(typeof MessageEvent !== "undefined").toBe(true); + expect(typeof TextEncoder !== "undefined").toBe(true); + expect(typeof WebSocket !== "undefined").toBe(true); + expect(typeof Blob !== "undefined").toBe(true); + expect(typeof FormData !== "undefined").toBe(true); +}); + +test("CloseEvent", () => { + var event = new CloseEvent("close", { reason: "world" }); + expect(event.type).toBe("close"); + const target = new EventTarget(); + var called = false; + target.addEventListener("close", ({ type, reason }) => { + expect(type).toBe("close"); + expect(reason).toBe("world"); + called = true; + }); + target.dispatchEvent(event); + expect(called).toBe(true); +}); + +test("MessageEvent", () => { + var event = new MessageEvent("message", { data: "world" }); + expect(event.type).toBe("message"); + const target = new EventTarget(); + var called = false; + target.addEventListener("message", ({ type, data }) => { + expect(type).toBe("message"); + expect(data).toBe("world"); + called = true; + }); + target.dispatchEvent(event); + expect(called).toBe(true); +}); + +it("crypto.getRandomValues", () => { + var foo = new Uint8Array(32); + + // run it once buffered and unbuffered + { + var array = crypto.getRandomValues(foo); + expect(array).toBe(foo); + expect(array.reduce((sum, a) => (sum += a === 0), 0) != foo.length).toBe(true); + } + + // disable it for this block because it tends to get stuck here running the GC forever + withoutAggressiveGC(() => { + // run it again to check that the fast path works + for (var i = 0; i < 9000; i++) { + var array = crypto.getRandomValues(foo); + expect(array).toBe(foo); + } + }); + + // run it on a large input + expect(!!crypto.getRandomValues(new Uint8Array(8096)).find(a => a > 0)).toBe(true); + + { + // any additional input into getRandomValues() makes it unbuffered + var array = crypto.getRandomValues(foo, "unbuffered"); + expect(array).toBe(foo); + expect(array.reduce((sum, a) => (sum += a === 0), 0) != foo.length).toBe(true); + } +}); + +// not actually a web global +it("crypto.timingSafeEqual", () => { + const crypto = import.meta.require("node:crypto"); + var uuidStr = crypto.randomUUID(); + expect(uuidStr.length).toBe(36); + expect(uuidStr[8]).toBe("-"); + expect(uuidStr[13]).toBe("-"); + expect(uuidStr[18]).toBe("-"); + expect(uuidStr[23]).toBe("-"); + const uuid = Buffer.from(uuidStr); + + expect(crypto.timingSafeEqual(uuid, uuid)).toBe(true); + expect(crypto.timingSafeEqual(uuid, uuid.slice())).toBe(true); + try { + crypto.timingSafeEqual(uuid, uuid.slice(1)); + expect(false).toBe(true); + } catch (e) {} + + try { + crypto.timingSafeEqual(uuid, uuid.slice(0, uuid.length - 2)); + expect(false).toBe(true); + } catch (e) { + expect(e.message).toBe("Input buffers must have the same length"); + } + + try { + expect(crypto.timingSafeEqual(uuid, crypto.randomUUID())).toBe(false); + expect(false).toBe(true); + } catch (e) { + expect(e.name).toBe("TypeError"); + } + + var shorter = uuid.slice(0, 1); + for (let i = 0; i < 9000; i++) { + if (!crypto.timingSafeEqual(shorter, shorter)) throw new Error("fail"); + } +}); + +it("crypto.randomUUID", () => { + var uuid = crypto.randomUUID(); + expect(uuid.length).toBe(36); + expect(uuid[8]).toBe("-"); + expect(uuid[13]).toBe("-"); + expect(uuid[18]).toBe("-"); + expect(uuid[23]).toBe("-"); + + withoutAggressiveGC(() => { + // check that the fast path works + for (let i = 0; i < 9000; i++) { + var uuid2 = crypto.randomUUID(); + expect(uuid2.length).toBe(36); + expect(uuid2[8]).toBe("-"); + expect(uuid2[13]).toBe("-"); + expect(uuid2[18]).toBe("-"); + expect(uuid2[23]).toBe("-"); + } + }); +}); + +it("URL.prototype.origin", () => { + const url = new URL("https://html.spec.whatwg.org/"); + const { origin, host, hostname } = url; + + expect(hostname).toBe("html.spec.whatwg.org"); + expect(host).toBe("html.spec.whatwg.org"); + expect(origin).toBe("https://html.spec.whatwg.org"); +}); + +test("navigator", () => { + expect(globalThis.navigator !== undefined).toBe(true); + const version = process.versions.bun; + const userAgent = `Bun/${version}`; + expect(navigator.hardwareConcurrency > 0).toBe(true); + expect(navigator.userAgent).toBe(userAgent); +}); |