// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // deno-lint-ignore-file no-node-globals import { assert, assertEquals, assertRejects, assertThrows, } from "./test_util.ts"; Deno.test(function globalThisExists() { assert(globalThis != null); }); Deno.test(function noInternalGlobals() { // globalThis.__bootstrap should not be there. for (const key of Object.keys(globalThis)) { assert(!key.startsWith("_")); } }); Deno.test(function selfExists() { assert(self != null); }); Deno.test(function globalThisWindowEqualsUndefined() { assert(globalThis.window === undefined); }); Deno.test(function globalThisEqualsSelf() { assert(globalThis === self); }); Deno.test(function globalThisConstructorLength() { assert(globalThis.constructor.length === 0); }); Deno.test(function globalThisInstanceofEventTarget() { assert(globalThis instanceof EventTarget); }); Deno.test(function navigatorInstanceofNavigator() { // TODO(nayeemrmn): Add `Navigator` to deno_lint globals. // deno-lint-ignore no-undef assert(navigator instanceof Navigator); }); Deno.test(function DenoNamespaceExists() { assert(Deno != null); }); Deno.test(function DenoNamespaceIsNotFrozen() { assert(!Object.isFrozen(Deno)); }); Deno.test(function webAssemblyExists() { assert(typeof WebAssembly.compile === "function"); }); // @ts-ignore This is not publicly typed namespace, but it's there for sure. const core = Deno[Deno.internal].core; Deno.test(function DenoNamespaceConfigurable() { const desc = Object.getOwnPropertyDescriptor(globalThis, "Deno"); assert(desc); assert(desc.configurable); assert(!desc.writable); }); Deno.test(function DenoCoreNamespaceIsImmutable() { const { print } = core; try { core.print = 1; } catch { // pass } assert(print === core.print); try { delete core.print; } catch { // pass } assert(print === core.print); }); Deno.test(async function windowQueueMicrotask() { let resolve1: () => void | undefined; let resolve2: () => void | undefined; let microtaskDone = false; const p1 = new Promise((res) => { resolve1 = () => { microtaskDone = true; res(); }; }); const p2 = new Promise((res) => { resolve2 = () => { assert(microtaskDone); res(); }; }); globalThis.queueMicrotask(resolve1!); setTimeout(resolve2!, 0); await p1; await p2; }); Deno.test(function webApiGlobalThis() { assert(globalThis.FormData !== null); assert(globalThis.TextEncoder !== null); assert(globalThis.TextEncoderStream !== null); assert(globalThis.TextDecoder !== null); assert(globalThis.TextDecoderStream !== null); assert(globalThis.CountQueuingStrategy !== null); assert(globalThis.ByteLengthQueuingStrategy !== null); }); Deno.test(function windowNameIsDefined() { assertEquals(typeof globalThis.name, "string"); assertEquals(name, ""); name = "foobar"; assertEquals(name, "foobar"); name = ""; assertEquals(name, ""); }); Deno.test(async function promiseWithResolvers() { { const { promise, resolve } = Promise.withResolvers(); resolve(true); assert(await promise); } { const { promise, reject } = Promise.withResolvers(); reject(new Error("boom!")); await assertRejects(() => promise, Error, "boom!"); } }); Deno.test(async function arrayFromAsync() { // Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync#examples // Thank you. const asyncIterable = (async function* () { for (let i = 0; i < 5; i++) { await new Promise((resolve) => setTimeout(resolve, 10 * i)); yield i; } })(); const a = await Array.fromAsync(asyncIterable); assertEquals(a, [0, 1, 2, 3, 4]); const b = await Array.fromAsync(new Map([[1, 2], [3, 4]])); assertEquals(b, [[1, 2], [3, 4]]); }); // Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy#examples Deno.test(function objectGroupBy() { const inventory = [ { name: "asparagus", type: "vegetables", quantity: 5 }, { name: "bananas", type: "fruit", quantity: 0 }, { name: "goat", type: "meat", quantity: 23 }, { name: "cherries", type: "fruit", quantity: 5 }, { name: "fish", type: "meat", quantity: 22 }, ]; const result = Object.groupBy(inventory, ({ type }) => type); assertEquals(result, { vegetables: [ { name: "asparagus", type: "vegetables", quantity: 5 }, ], fruit: [ { name: "bananas", type: "fruit", quantity: 0 }, { name: "cherries", type: "fruit", quantity: 5 }, ], meat: [ { name: "goat", type: "meat", quantity: 23 }, { name: "fish", type: "meat", quantity: 22 }, ], }); }); Deno.test(function objectGroupByEmpty() { const empty: string[] = []; const result = Object.groupBy(empty, () => "abc"); assertEquals(result.abc, undefined); }); // Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/groupBy#examples Deno.test(function mapGroupBy() { const inventory = [ { name: "asparagus", type: "vegetables", quantity: 9 }, { name: "bananas", type: "fruit", quantity: 5 }, { name: "goat", type: "meat", quantity: 23 }, { name: "cherries", type: "fruit", quantity: 12 }, { name: "fish", type: "meat", quantity: 22 }, ]; const restock = { restock: true }; const sufficient = { restock: false }; const result = Map.groupBy( inventory, ({ quantity }) => quantity < 6 ? restock : sufficient, ); assertEquals(result.get(restock), [{ name: "bananas", type: "fruit", quantity: 5, }]); }); Deno.test(function nodeGlobalsRaise() { assertThrows(() => { // @ts-ignore yes that's the point Buffer; }, ReferenceError); });