diff options
author | haturau <135221985+haturatu@users.noreply.github.com> | 2024-11-20 01:20:47 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-20 01:20:47 +0900 |
commit | 85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch) | |
tree | face0aecaac53e93ce2f23b53c48859bcf1a36ec /tests/unit_node | |
parent | 67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff) | |
parent | 186b52731c6bb326c4d32905c5e732d082e83465 (diff) |
Merge branch 'denoland:main' into main
Diffstat (limited to 'tests/unit_node')
-rw-r--r-- | tests/unit_node/_fs/_fs_stat_test.ts | 7 | ||||
-rw-r--r-- | tests/unit_node/child_process_test.ts | 16 | ||||
-rw-r--r-- | tests/unit_node/crypto/crypto_key_test.ts | 44 | ||||
-rw-r--r-- | tests/unit_node/crypto/crypto_misc_test.ts | 10 | ||||
-rw-r--r-- | tests/unit_node/fetch_test.ts | 18 | ||||
-rw-r--r-- | tests/unit_node/fs_test.ts | 77 | ||||
-rw-r--r-- | tests/unit_node/http2_test.ts | 5 | ||||
-rw-r--r-- | tests/unit_node/http_test.ts | 108 | ||||
-rw-r--r-- | tests/unit_node/perf_hooks_test.ts | 22 | ||||
-rw-r--r-- | tests/unit_node/process_test.ts | 39 | ||||
-rw-r--r-- | tests/unit_node/timers_test.ts | 151 | ||||
-rw-r--r-- | tests/unit_node/tls_test.ts | 28 | ||||
-rw-r--r-- | tests/unit_node/util_test.ts | 5 | ||||
-rw-r--r-- | tests/unit_node/zlib_test.ts | 20 |
14 files changed, 516 insertions, 34 deletions
diff --git a/tests/unit_node/_fs/_fs_stat_test.ts b/tests/unit_node/_fs/_fs_stat_test.ts index 02c620e2d..e42aa34a9 100644 --- a/tests/unit_node/_fs/_fs_stat_test.ts +++ b/tests/unit_node/_fs/_fs_stat_test.ts @@ -18,9 +18,11 @@ export function assertStats(actual: Stats, expected: Deno.FileInfo) { assertEquals(actual.atime?.getTime(), expected.atime?.getTime()); assertEquals(actual.mtime?.getTime(), expected.mtime?.getTime()); assertEquals(actual.birthtime?.getTime(), expected.birthtime?.getTime()); + assertEquals(actual.ctime?.getTime(), expected.ctime?.getTime()); assertEquals(actual.atimeMs ?? undefined, expected.atime?.getTime()); assertEquals(actual.mtimeMs ?? undefined, expected.mtime?.getTime()); assertEquals(actual.birthtimeMs ?? undefined, expected.birthtime?.getTime()); + assertEquals(actual.ctimeMs ?? undefined, expected.ctime?.getTime()); assertEquals(actual.isFile(), expected.isFile); assertEquals(actual.isDirectory(), expected.isDirectory); assertEquals(actual.isSymbolicLink(), expected.isSymlink); @@ -49,6 +51,7 @@ export function assertStatsBigInt( assertEquals(actual.atime?.getTime(), expected.atime?.getTime()); assertEquals(actual.mtime?.getTime(), expected.mtime?.getTime()); assertEquals(actual.birthtime?.getTime(), expected.birthtime?.getTime()); + assertEquals(actual.ctime?.getTime(), expected.ctime?.getTime()); assertEquals( actual.atimeMs === null ? undefined : Number(actual.atimeMs), expected.atime?.getTime(), @@ -61,6 +64,10 @@ export function assertStatsBigInt( actual.birthtimeMs === null ? undefined : Number(actual.birthtimeMs), expected.birthtime?.getTime(), ); + assertEquals( + actual.ctimeMs === null ? undefined : Number(actual.ctimeMs), + expected.ctime?.getTime(), + ); assertEquals(actual.atimeNs === null, actual.atime === null); assertEquals(actual.mtimeNs === null, actual.mtime === null); assertEquals(actual.birthtimeNs === null, actual.birthtime === null); diff --git a/tests/unit_node/child_process_test.ts b/tests/unit_node/child_process_test.ts index f776fa4ac..0ea3c46cf 100644 --- a/tests/unit_node/child_process_test.ts +++ b/tests/unit_node/child_process_test.ts @@ -1045,3 +1045,19 @@ Deno.test(async function sendAfterClosedThrows() { await timeout.promise; }); + +Deno.test(async function noWarningsFlag() { + const code = ``; + const file = await Deno.makeTempFile(); + await Deno.writeTextFile(file, code); + const timeout = withTimeout<void>(); + const child = CP.fork(file, [], { + execArgv: ["--no-warnings"], + stdio: ["inherit", "inherit", "inherit", "ipc"], + }); + child.on("close", () => { + timeout.resolve(); + }); + + await timeout.promise; +}); diff --git a/tests/unit_node/crypto/crypto_key_test.ts b/tests/unit_node/crypto/crypto_key_test.ts index 7995ce5d3..5d206acc7 100644 --- a/tests/unit_node/crypto/crypto_key_test.ts +++ b/tests/unit_node/crypto/crypto_key_test.ts @@ -656,3 +656,47 @@ z6TExWlQMjt66nV7R8cRAkzmABrG+NW3e8Zpac7Lkuv+zu0S+K7c assertEquals(publicKey.type, "public"); assertEquals(publicKey.asymmetricKeyType, "rsa"); }); + +// https://github.com/denoland/deno/issues/26188 +Deno.test("generateKeyPair large pem", function () { + const passphrase = "mypassphrase"; + const cipher = "aes-256-cbc"; + const modulusLength = 4096; + + generateKeyPairSync("rsa", { + modulusLength, + publicKeyEncoding: { + type: "spki", + format: "pem", + }, + privateKeyEncoding: { + type: "pkcs8", + format: "pem", + cipher, + passphrase, + }, + }); +}); + +Deno.test("generateKeyPair promisify", async () => { + const passphrase = "mypassphrase"; + const cipher = "aes-256-cbc"; + const modulusLength = 4096; + + const { privateKey, publicKey } = await promisify(generateKeyPair)("rsa", { + modulusLength, + publicKeyEncoding: { + type: "spki", + format: "pem", + }, + privateKeyEncoding: { + type: "pkcs8", + format: "pem", + cipher, + passphrase, + }, + }); + + assert(publicKey.startsWith("-----BEGIN PUBLIC KEY-----")); + assert(privateKey.startsWith("-----BEGIN PRIVATE KEY-----")); +}); diff --git a/tests/unit_node/crypto/crypto_misc_test.ts b/tests/unit_node/crypto/crypto_misc_test.ts index 47a48b1bf..007009339 100644 --- a/tests/unit_node/crypto/crypto_misc_test.ts +++ b/tests/unit_node/crypto/crypto_misc_test.ts @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { randomFillSync, randomUUID } from "node:crypto"; +import { randomFillSync, randomUUID, timingSafeEqual } from "node:crypto"; +import { Buffer } from "node:buffer"; import { assert, assertEquals } from "../../unit/test_util.ts"; import { assertNotEquals } from "@std/assert"; @@ -28,3 +29,10 @@ Deno.test("[node/crypto.randomFillSync] array buffer view", () => { assertEquals(buf.subarray(0, 8), new Uint8Array(8)); assertEquals(buf.subarray(24, 32), new Uint8Array(8)); }); + +Deno.test("[node/crypto.timingSafeEqual] compares equal Buffer with different byteOffset", () => { + const a = Buffer.from([212, 213]); + const b = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 212, 213]).subarray(8); + + assert(timingSafeEqual(a, b)); +}); diff --git a/tests/unit_node/fetch_test.ts b/tests/unit_node/fetch_test.ts new file mode 100644 index 000000000..399d6052a --- /dev/null +++ b/tests/unit_node/fetch_test.ts @@ -0,0 +1,18 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals } from "@std/assert"; +import { createReadStream } from "node:fs"; + +Deno.test("fetch node stream", async () => { + const file = createReadStream("tests/testdata/assets/fixture.json"); + + const response = await fetch("http://localhost:4545/echo_server", { + method: "POST", + body: file, + }); + + assertEquals( + await response.text(), + await Deno.readTextFile("tests/testdata/assets/fixture.json"), + ); +}); diff --git a/tests/unit_node/fs_test.ts b/tests/unit_node/fs_test.ts index 2d1465aec..631608d7c 100644 --- a/tests/unit_node/fs_test.ts +++ b/tests/unit_node/fs_test.ts @@ -1,11 +1,13 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { assert, assertEquals, assertThrows } from "@std/assert"; +/// <reference lib="deno.ns" /> +import { assert, assertEquals, assertRejects, assertThrows } from "@std/assert"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { closeSync, constants, + copyFileSync, createWriteStream, existsSync, lstatSync, @@ -20,9 +22,11 @@ import { } from "node:fs"; import { constants as fsPromiseConstants, + copyFile, cp, FileHandle, open, + stat, writeFile, } from "node:fs/promises"; import process from "node:process"; @@ -121,6 +125,48 @@ Deno.test( ); Deno.test( + "[node/fs statSync] throw error with path information", + () => { + const file = "non-exist-file"; + const fileUrl = new URL(file, import.meta.url); + + assertThrows(() => { + statSync(file); + }, "Error: ENOENT: no such file or directory, stat 'non-exist-file'"); + + assertThrows(() => { + statSync(fileUrl); + }, `Error: ENOENT: no such file or directory, stat '${fileUrl.pathname}'`); + }, +); + +Deno.test( + "[node/fs/promises stat] throw error with path information", + async () => { + const file = "non-exist-file"; + const fileUrl = new URL(file, import.meta.url); + + try { + await stat(file); + } catch (error: unknown) { + assertEquals( + `${error}`, + "Error: ENOENT: no such file or directory, stat 'non-exist-file'", + ); + } + + try { + await stat(fileUrl); + } catch (error: unknown) { + assertEquals( + `${error}`, + `Error: ENOENT: no such file or directory, stat '${fileUrl.pathname}'`, + ); + } + }, +); + +Deno.test( "[node/fs/promises cp] copy file", async () => { const src = mkdtempSync(join(tmpdir(), "foo-")) + "/test.txt"; @@ -212,3 +258,32 @@ Deno.test("[node/fs] readSync works", () => { assertEquals(bytesRead, 12); closeSync(fd!); }); + +Deno.test("[node/fs] copyFile COPYFILE_EXCL works", async () => { + const dir = mkdtempSync(join(tmpdir(), "foo-")); + const src = join(dir, "src.txt"); + const dest = join(dir, "dest.txt"); + await writeFile(src, ""); + await copyFile(src, dest, fsPromiseConstants.COPYFILE_EXCL); + assert(existsSync(dest)); + await assertRejects(() => + copyFile(src, dest, fsPromiseConstants.COPYFILE_EXCL) + ); + const dest2 = join(dir, "dest2.txt"); + copyFileSync(src, dest2, fsPromiseConstants.COPYFILE_EXCL); + assert(existsSync(dest2)); + assertThrows(() => + copyFileSync(src, dest2, fsPromiseConstants.COPYFILE_EXCL) + ); +}); + +Deno.test("[node/fs] statSync throws ENOENT for invalid path containing colon in it", () => { + // deno-lint-ignore no-explicit-any + const err: any = assertThrows(() => { + // Note: Deno.stat throws ERROR_INVALID_NAME (os error 123) instead of + // ERROR_FILE_NOT_FOUND (os error 2) on windows. This case checks that + // ERROR_INVALID_NAME is mapped to ENOENT correctly on node compat layer. + statSync("jsr:@std/assert"); + }); + assertEquals(err.code, "ENOENT"); +}); diff --git a/tests/unit_node/http2_test.ts b/tests/unit_node/http2_test.ts index 7473a487a..c540c90f7 100644 --- a/tests/unit_node/http2_test.ts +++ b/tests/unit_node/http2_test.ts @@ -10,6 +10,11 @@ import * as net from "node:net"; import { assert, assertEquals } from "@std/assert"; import { curlRequest } from "../unit/test_util.ts"; +// Increase the timeout for the auto select family to avoid flakiness +net.setDefaultAutoSelectFamilyAttemptTimeout( + net.getDefaultAutoSelectFamilyAttemptTimeout() * 30, +); + for (const url of ["http://localhost:4246", "https://localhost:4247"]) { Deno.test(`[node/http2 client] ${url}`, { ignore: Deno.build.os === "windows", diff --git a/tests/unit_node/http_test.ts b/tests/unit_node/http_test.ts index f85b1466b..2b3b8f509 100644 --- a/tests/unit_node/http_test.ts +++ b/tests/unit_node/http_test.ts @@ -3,10 +3,14 @@ // deno-lint-ignore-file no-console import EventEmitter from "node:events"; -import http, { type RequestOptions, type ServerResponse } from "node:http"; +import http, { + IncomingMessage, + type RequestOptions, + ServerResponse, +} from "node:http"; import url from "node:url"; import https from "node:https"; -import net from "node:net"; +import net, { Socket } from "node:net"; import fs from "node:fs"; import { text } from "node:stream/consumers"; @@ -1143,6 +1147,34 @@ Deno.test("[node/http] ServerResponse appendHeader set-cookie", async () => { await promise; }); +Deno.test("[node/http] ServerResponse header names case insensitive", async () => { + const { promise, resolve } = Promise.withResolvers<void>(); + const server = http.createServer((_req, res) => { + res.setHeader("Content-Length", "12345"); + res.removeHeader("content-length"); + assertEquals(res.getHeader("Content-Length"), undefined); + assert(!res.hasHeader("Content-Length")); + res.appendHeader("content-length", "12345"); + res.removeHeader("Content-Length"); + assertEquals(res.getHeader("content-length"), undefined); + assert(!res.hasHeader("content-length")); + res.end("Hello World"); + }); + + server.listen(async () => { + const { port } = server.address() as { port: number }; + const res = await fetch(`http://localhost:${port}`); + assertEquals(res.headers.get("Content-Length"), null); + assertEquals(res.headers.get("content-length"), null); + assertEquals(await res.text(), "Hello World"); + server.close(() => { + resolve(); + }); + }); + + await promise; +}); + Deno.test("[node/http] IncomingMessage override", () => { const req = new http.IncomingMessage(new net.Socket()); // https://github.com/dougmoscrop/serverless-http/blob/3aaa6d0fe241109a8752efb011c242d249f32368/lib/request.js#L20-L30 @@ -1672,3 +1704,75 @@ Deno.test("[node/http] upgraded socket closes when the server closed without clo await clientSocketClosed.promise; await serverProcessClosed.promise; }); + +// deno-lint-ignore require-await +Deno.test("[node/http] ServerResponse.call()", async () => { + function Wrapper(this: unknown, req: IncomingMessage) { + ServerResponse.call(this, req); + } + Object.setPrototypeOf(Wrapper.prototype, ServerResponse.prototype); + + // deno-lint-ignore no-explicit-any + const wrapper = new (Wrapper as any)(new IncomingMessage(new Socket())); + + assert(wrapper instanceof ServerResponse); +}); + +Deno.test("[node/http] ServerResponse _header", async () => { + const { promise, resolve } = Promise.withResolvers<void>(); + const server = http.createServer((_req, res) => { + assert(Object.hasOwn(res, "_header")); + res.end(); + }); + + server.listen(async () => { + const { port } = server.address() as { port: number }; + const res = await fetch(`http://localhost:${port}`); + await res.body?.cancel(); + server.close(() => { + resolve(); + }); + }); + + await promise; +}); + +Deno.test("[node/http] ServerResponse connection", async () => { + const { promise, resolve } = Promise.withResolvers<void>(); + const server = http.createServer((_req, res) => { + assert(Object.hasOwn(res, "connection")); + assert(res.connection instanceof Socket); + res.end(); + }); + + server.listen(async () => { + const { port } = server.address() as { port: number }; + const res = await fetch(`http://localhost:${port}`); + await res.body?.cancel(); + server.close(() => { + resolve(); + }); + }); + + await promise; +}); + +Deno.test("[node/http] ServerResponse socket", async () => { + const { promise, resolve } = Promise.withResolvers<void>(); + const server = http.createServer((_req, res) => { + assert(Object.hasOwn(res, "socket")); + assert(res.socket instanceof Socket); + res.end(); + }); + + server.listen(async () => { + const { port } = server.address() as { port: number }; + const res = await fetch(`http://localhost:${port}`); + await res.body?.cancel(); + server.close(() => { + resolve(); + }); + }); + + await promise; +}); diff --git a/tests/unit_node/perf_hooks_test.ts b/tests/unit_node/perf_hooks_test.ts index d5b900041..83d006222 100644 --- a/tests/unit_node/perf_hooks_test.ts +++ b/tests/unit_node/perf_hooks_test.ts @@ -1,7 +1,11 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. import * as perfHooks from "node:perf_hooks"; -import { performance, PerformanceObserver } from "node:perf_hooks"; -import { assertEquals, assertThrows } from "@std/assert"; +import { + monitorEventLoopDelay, + performance, + PerformanceObserver, +} from "node:perf_hooks"; +import { assert, assertEquals, assertThrows } from "@std/assert"; Deno.test({ name: "[perf_hooks] performance", @@ -68,3 +72,17 @@ Deno.test("[perf_hooks]: eventLoopUtilization", () => { assertEquals(typeof obj.active, "number"); assertEquals(typeof obj.utilization, "number"); }); + +Deno.test("[perf_hooks]: monitorEventLoopDelay", async () => { + const e = monitorEventLoopDelay(); + assertEquals(e.count, 0); + e.enable(); + + await new Promise((resolve) => setTimeout(resolve, 100)); + + assert(e.min > 0); + assert(e.minBigInt > 0n); + assert(e.count > 0); + + e.disable(); +}); diff --git a/tests/unit_node/process_test.ts b/tests/unit_node/process_test.ts index 0e0f169d6..49de2dce1 100644 --- a/tests/unit_node/process_test.ts +++ b/tests/unit_node/process_test.ts @@ -25,7 +25,6 @@ import { assertThrows, fail, } from "@std/assert"; -import { assertSpyCall, assertSpyCalls, spy } from "@std/testing/mock"; import { stripAnsiCode } from "@std/fmt/colors"; import * as path from "@std/path"; import { delay } from "@std/async/delay"; @@ -239,33 +238,6 @@ Deno.test({ }, }); -Deno.test({ - name: "process.on - ignored signals on windows", - ignore: Deno.build.os !== "windows", - fn() { - const ignoredSignals = ["SIGHUP", "SIGUSR1", "SIGUSR2"]; - - for (const signal of ignoredSignals) { - using consoleSpy = spy(console, "warn"); - const handler = () => {}; - process.on(signal, handler); - process.off(signal, handler); - assertSpyCall(consoleSpy, 0, { - args: [`Ignoring signal "${signal}" on Windows`], - }); - } - - { - using consoleSpy = spy(console, "warn"); - const handler = () => {}; - process.on("SIGTERM", handler); - process.off("SIGTERM", handler); - // No warning is made for SIGTERM - assertSpyCalls(consoleSpy, 0); - } - }, -}); - Deno.test( { permissions: { run: true, read: true } }, async function processKill() { @@ -1175,3 +1147,14 @@ Deno.test("process.cpuUsage()", () => { assert(typeof cpuUsage.user === "number"); assert(typeof cpuUsage.system === "number"); }); + +Deno.test("process.stdout.columns writable", () => { + process.stdout.columns = 80; + assertEquals(process.stdout.columns, 80); +}); + +Deno.test("getBuiltinModule", () => { + assert(process.getBuiltinModule("fs")); + assert(process.getBuiltinModule("node:fs")); + assertEquals(process.getBuiltinModule("something"), undefined); +}); diff --git a/tests/unit_node/timers_test.ts b/tests/unit_node/timers_test.ts index 868ba21d6..ddc6dc0d8 100644 --- a/tests/unit_node/timers_test.ts +++ b/tests/unit_node/timers_test.ts @@ -3,6 +3,7 @@ import { assert, fail } from "@std/assert"; import * as timers from "node:timers"; import * as timersPromises from "node:timers/promises"; +import { assertEquals } from "@std/assert"; Deno.test("[node/timers setTimeout]", () => { { @@ -108,3 +109,153 @@ Deno.test("[node/timers setImmediate returns Immediate object]", () => { imm.hasRef(); clearImmediate(imm); }); + +Deno.test({ + name: "setInterval yields correct values at expected intervals", + async fn() { + // Test configuration + const CONFIG = { + expectedValue: 42, + intervalMs: 100, + iterations: 3, + tolerancePercent: 50, + }; + + const { setInterval } = timersPromises; + const results: Array<{ value: number; timestamp: number }> = []; + const startTime = Date.now(); + + const iterator = setInterval(CONFIG.intervalMs, CONFIG.expectedValue); + + for await (const value of iterator) { + results.push({ + value, + timestamp: Date.now(), + }); + if (results.length === CONFIG.iterations) { + break; + } + } + + const values = results.map((r) => r.value); + assertEquals( + values, + Array(CONFIG.iterations).fill(CONFIG.expectedValue), + `Each iteration should yield ${CONFIG.expectedValue}`, + ); + + const intervals = results.slice(1).map((result, index) => ({ + interval: result.timestamp - results[index].timestamp, + iterationNumber: index + 1, + })); + + const toleranceMs = (CONFIG.tolerancePercent / 100) * CONFIG.intervalMs; + const expectedRange = { + min: CONFIG.intervalMs - toleranceMs, + max: CONFIG.intervalMs + toleranceMs, + }; + + intervals.forEach(({ interval, iterationNumber }) => { + const isWithinTolerance = interval >= expectedRange.min && + interval <= expectedRange.max; + + assertEquals( + isWithinTolerance, + true, + `Iteration ${iterationNumber}: Interval ${interval}ms should be within ` + + `${expectedRange.min}ms and ${expectedRange.max}ms ` + + `(${CONFIG.tolerancePercent}% tolerance of ${CONFIG.intervalMs}ms)`, + ); + }); + + const totalDuration = results[results.length - 1].timestamp - startTime; + const expectedDuration = CONFIG.intervalMs * CONFIG.iterations; + const isDurationReasonable = + totalDuration >= (expectedDuration - toleranceMs) && + totalDuration <= (expectedDuration + toleranceMs); + + assertEquals( + isDurationReasonable, + true, + `Total duration ${totalDuration}ms should be close to ${expectedDuration}ms ` + + `(within ${toleranceMs}ms tolerance)`, + ); + + const timestamps = results.map((r) => r.timestamp); + const areTimestampsOrdered = timestamps.every((timestamp, i) => + i === 0 || timestamp > timestamps[i - 1] + ); + + assertEquals( + areTimestampsOrdered, + true, + "Timestamps should be strictly increasing", + ); + }, +}); + +Deno.test({ + name: "setInterval with AbortSignal stops after expected duration", + async fn() { + const INTERVAL_MS = 500; + const TOTAL_DURATION_MS = 3000; + const TOLERANCE_MS = 500; + + const abortController = new AbortController(); + const { setInterval } = timersPromises; + + // Set up abort after specified duration + const abortTimeout = timers.setTimeout(() => { + abortController.abort(); + }, TOTAL_DURATION_MS); + + // Track iterations and timing + const startTime = Date.now(); + const iterations: number[] = []; + + try { + for await ( + const _timestamp of setInterval(INTERVAL_MS, undefined, { + signal: abortController.signal, + }) + ) { + iterations.push(Date.now() - startTime); + } + } catch (error) { + if (error instanceof Error && error.name !== "AbortError") { + throw error; + } + } finally { + timers.clearTimeout(abortTimeout); + } + + // Validate timing + const totalDuration = iterations[iterations.length - 1]; + const isWithinTolerance = + totalDuration >= (TOTAL_DURATION_MS - TOLERANCE_MS) && + totalDuration <= (TOTAL_DURATION_MS + TOLERANCE_MS); + + assertEquals( + isWithinTolerance, + true, + `Total duration ${totalDuration}ms should be within ±${TOLERANCE_MS}ms of ${TOTAL_DURATION_MS}ms`, + ); + + // Validate interval consistency + const intervalDeltas = iterations.slice(1).map((time, i) => + time - iterations[i] + ); + + intervalDeltas.forEach((delta, i) => { + const isIntervalValid = delta >= (INTERVAL_MS - 50) && + delta <= (INTERVAL_MS + 50); + assertEquals( + isIntervalValid, + true, + `Interval ${ + i + 1 + } duration (${delta}ms) should be within ±50ms of ${INTERVAL_MS}ms`, + ); + }); + }, +}); diff --git a/tests/unit_node/tls_test.ts b/tests/unit_node/tls_test.ts index 93eacd5ec..43d6205b0 100644 --- a/tests/unit_node/tls_test.ts +++ b/tests/unit_node/tls_test.ts @@ -229,3 +229,31 @@ Deno.test("tls.rootCertificates is not empty", () => { (tls.rootCertificates as string[]).push("new cert"); }, TypeError); }); + +Deno.test("TLSSocket.alpnProtocol is set for client", async () => { + const listener = Deno.listenTls({ + hostname: "localhost", + port: 0, + key, + cert, + alpnProtocols: ["a"], + }); + const outgoing = tls.connect({ + host: "::1", + servername: "localhost", + port: listener.addr.port, + ALPNProtocols: ["a"], + secureContext: { + ca: rootCaCert, + // deno-lint-ignore no-explicit-any + } as any, + }); + + const conn = await listener.accept(); + const handshake = await conn.handshake(); + assertEquals(handshake.alpnProtocol, "a"); + conn.close(); + outgoing.destroy(); + listener.close(); + await new Promise((resolve) => outgoing.on("close", resolve)); +}); diff --git a/tests/unit_node/util_test.ts b/tests/unit_node/util_test.ts index a47c231a1..6267018b1 100644 --- a/tests/unit_node/util_test.ts +++ b/tests/unit_node/util_test.ts @@ -353,3 +353,8 @@ Deno.test("[util] styleText()", () => { const redText = util.styleText("red", "error"); assertEquals(redText, "\x1B[31merror\x1B[39m"); }); + +Deno.test("[util] styleText() with array of formats", () => { + const colored = util.styleText(["red", "green"], "error"); + assertEquals(colored, "\x1b[32m\x1b[31merror\x1b[39m\x1b[39m"); +}); diff --git a/tests/unit_node/zlib_test.ts b/tests/unit_node/zlib_test.ts index 8bce5ce7d..de2d2450d 100644 --- a/tests/unit_node/zlib_test.ts +++ b/tests/unit_node/zlib_test.ts @@ -7,9 +7,11 @@ import { brotliCompressSync, brotliDecompressSync, constants, + crc32, createBrotliCompress, createBrotliDecompress, createDeflate, + gzip, gzipSync, unzipSync, } from "node:zlib"; @@ -210,3 +212,21 @@ Deno.test("createBrotliCompress params", async () => { ); assertEquals(output.length, input.length); }); + +Deno.test("gzip() and gzipSync() accept ArrayBuffer", async () => { + const deffered = Promise.withResolvers<void>(); + const buf = new ArrayBuffer(0); + let output: Buffer; + gzip(buf, (_err, data) => { + output = data; + deffered.resolve(); + }); + await deffered.promise; + assert(output! instanceof Buffer); + const outputSync = gzipSync(buf); + assert(outputSync instanceof Buffer); +}); + +Deno.test("crc32()", () => { + assertEquals(crc32("hello world"), 222957957); +}); |