From 49e3ee010c7d4423fbab89bf12749235e156c9be Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 5 Sep 2024 09:22:52 +0200 Subject: feat(ext/node): add abort helpers, process & streams fix (#25262) This commit adds: - `addAbortListener` in `node:events` - `aborted` in `node:util` - `execPath` and `execvArgs` named export from `node:process` - `getDefaultHighWaterMark` from `node:stream` The `execPath` is very hacky - because module namespaces can not have real getters, `execPath` is an object with a `toString()` method that on call returns the actual `execPath`, and replaces the `execPath` binding with the string. This is done so that we don't require the `execPath` permission on startup. --- tests/unit_node/events_test.ts | 13 ++++++++++++- tests/unit_node/process_test.ts | 10 ++++++++++ tests/unit_node/stream_test.ts | 9 ++++++++- tests/unit_node/util_test.ts | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) (limited to 'tests/unit_node') diff --git a/tests/unit_node/events_test.ts b/tests/unit_node/events_test.ts index 1fc7ad1e3..82808d523 100644 --- a/tests/unit_node/events_test.ts +++ b/tests/unit_node/events_test.ts @@ -1,6 +1,7 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import events, { EventEmitter } from "node:events"; +// @ts-expect-error: @types/node is outdated +import events, { addAbortListener, EventEmitter } from "node:events"; EventEmitter.captureRejections = true; @@ -34,3 +35,13 @@ Deno.test("eventemitter async resource", () => { // @ts-ignore: @types/node is outdated foo.emit("bar"); }); + +Deno.test("addAbortListener", async () => { + const { promise, resolve } = Promise.withResolvers(); + const abortController = new AbortController(); + addAbortListener(abortController.signal, () => { + resolve(); + }); + abortController.abort(); + await promise; +}); diff --git a/tests/unit_node/process_test.ts b/tests/unit_node/process_test.ts index a647b0369..962877935 100644 --- a/tests/unit_node/process_test.ts +++ b/tests/unit_node/process_test.ts @@ -7,6 +7,8 @@ import process, { argv, argv0 as importedArgv0, env, + execArgv as importedExecArgv, + execPath as importedExecPath, geteuid, pid as importedPid, platform as importedPlatform, @@ -1121,3 +1123,11 @@ Deno.test("process.listeners - include SIG* events", () => { Deno.test(function processVersionsOwnProperty() { assert(Object.prototype.hasOwnProperty.call(process, "versions")); }); + +Deno.test(function importedExecArgvTest() { + assert(Array.isArray(importedExecArgv)); +}); + +Deno.test(function importedExecPathTest() { + assertEquals(importedExecPath, Deno.execPath()); +}); diff --git a/tests/unit_node/stream_test.ts b/tests/unit_node/stream_test.ts index a54f8b421..8d4970146 100644 --- a/tests/unit_node/stream_test.ts +++ b/tests/unit_node/stream_test.ts @@ -1,8 +1,10 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { assert } from "@std/assert"; +import { assert, assertEquals } from "@std/assert"; import { fromFileUrl, relative } from "@std/path"; import { pipeline } from "node:stream/promises"; +// @ts-expect-error: @types/node is outdated +import { getDefaultHighWaterMark } from "node:stream"; import { createReadStream, createWriteStream } from "node:fs"; Deno.test("stream/promises pipeline", async () => { @@ -23,3 +25,8 @@ Deno.test("stream/promises pipeline", async () => { // pass } }); + +Deno.test("stream getDefaultHighWaterMark", () => { + assertEquals(getDefaultHighWaterMark(false), 16 * 1024); + assertEquals(getDefaultHighWaterMark(true), 16); +}); diff --git a/tests/unit_node/util_test.ts b/tests/unit_node/util_test.ts index 2b639538c..edd500262 100644 --- a/tests/unit_node/util_test.ts +++ b/tests/unit_node/util_test.ts @@ -330,3 +330,21 @@ Deno.test("[util] debuglog() and debug()", () => { assertEquals(util.debuglog, util.debug); assertEquals(utilDefault.debuglog, utilDefault.debug); }); + +Deno.test("[util] aborted()", async () => { + const abortController = new AbortController(); + let done = false; + const promise = util.aborted( + // deno-lint-ignore no-explicit-any + abortController.signal as any, + abortController.signal, + ); + promise.then(() => { + done = true; + }); + await new Promise((r) => setTimeout(r, 100)); + assertEquals(done, false); + abortController.abort(); + await promise; + assertEquals(done, true); +}); -- cgit v1.2.3