Merge commit 'f472779' into kai/readline-test-fixes

This commit is contained in:
Kai Tamkun
2024-12-10 15:16:29 -08:00
88 changed files with 4025 additions and 666 deletions

View File

@@ -1,9 +1,7 @@
import readline from "node:readline";
var {
// Flags: --expose-internals
const {
utils: { getStringWidth },
// @ts-ignore
} = readline[Symbol.for("__BUN_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__")];
} = require("internal/readline/utils");
it("handles invisible ASCII character at any position", () => {
const visible = "a";

View File

@@ -4,12 +4,10 @@ import { EventEmitter } from "node:events";
import readline from "node:readline";
import { PassThrough, Writable } from "node:stream";
const { beforeEach, describe, it, createDoneDotAll, createCallCheckCtx, assert } = createTest(import.meta.path);
var {
const {
CSI,
utils: { getStringWidth, stripVTControlCharacters },
// @ts-ignore
} = readline[Symbol.for("__BUN_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__")];
} = require("internal/readline/utils");
// ----------------------------------------------------------------------------
// Helpers

View File

@@ -384,6 +384,57 @@ if (global.Storage) {
);
}
if (global.Bun) {
knownGlobals.push(
global.addEventListener,
global.alert,
global.confirm,
global.dispatchEvent,
global.postMessage,
global.prompt,
global.removeEventListener,
global.reportError,
global.Bun,
global.File,
global.process,
global.Blob,
global.Buffer,
global.BuildError,
global.BuildMessage,
global.HTMLRewriter,
global.Request,
global.ResolveError,
global.ResolveMessage,
global.Response,
global.TextDecoder,
global.AbortSignal,
global.BroadcastChannel,
global.CloseEvent,
global.DOMException,
global.ErrorEvent,
global.Event,
global.EventTarget,
global.FormData,
global.Headers,
global.MessageChannel,
global.MessageEvent,
global.MessagePort,
global.PerformanceEntry,
global.PerformanceObserver,
global.PerformanceObserverEntryList,
global.PerformanceResourceTiming,
global.PerformanceServerTiming,
global.PerformanceTiming,
global.TextEncoder,
global.URL,
global.URLSearchParams,
global.WebSocket,
global.Worker,
global.onmessage,
global.onerror
);
}
function allowGlobals(...allowlist) {
knownGlobals = knownGlobals.concat(allowlist);
}

View File

@@ -0,0 +1,17 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { AsyncLocalStorage } = require('async_hooks');
[1, false, '', {}, []].forEach((i) => {
assert.throws(() => AsyncLocalStorage.bind(i), {
code: 'ERR_INVALID_ARG_TYPE'
});
});
const fn = common.mustCall(AsyncLocalStorage.bind(() => 123));
assert.strictEqual(fn(), 123);
const fn2 = AsyncLocalStorage.bind(common.mustCall((arg) => assert.strictEqual(arg, 'test')));
fn2('test');

View File

@@ -0,0 +1,28 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { AsyncLocalStorage } = require('async_hooks');
const als = new AsyncLocalStorage();
// The _propagate function only exists on the old JavaScript implementation.
if (typeof als._propagate === 'function') {
// The als instance should be getting removed from the storageList in
// lib/async_hooks.js when exit(...) is called, therefore when the nested runs
// are called there should be no copy of the als in the storageList to run the
// _propagate method on.
als._propagate = common.mustNotCall('_propagate() should not be called');
}
const done = common.mustCall();
const data = true;
function run(count) {
if (count === 0) return done();
assert.notStrictEqual(als.getStore(), data);
als.run(data, () => {
als.exit(run, --count);
});
}
run(100);

View File

@@ -0,0 +1,33 @@
// Flags: --expose-internals
'use strict';
require('../common');
const { internalBinding } = require('internal/test/binding');
const constants = internalBinding('constants');
const assert = require('assert');
assert.deepStrictEqual(
Object.keys(constants).sort(), ['crypto', 'fs', 'os', 'trace', 'zlib']
);
assert.deepStrictEqual(
Object.keys(constants.os).sort(), ['UV_UDP_REUSEADDR', 'dlopen', 'errno',
'priority', 'signals']
);
// Make sure all the constants objects don't inherit from Object.prototype
const inheritedProperties = Object.getOwnPropertyNames(Object.prototype);
function test(obj) {
assert(obj);
assert.strictEqual(Object.prototype.toString.call(obj), '[object Object]');
assert.strictEqual(Object.getPrototypeOf(obj), null);
inheritedProperties.forEach((property) => {
assert.strictEqual(property in obj, false);
});
}
[
constants, constants.crypto, constants.fs, constants.os, constants.trace,
constants.zlib, constants.os.dlopen, constants.os.errno, constants.os.signals,
].forEach(test);

View File

@@ -0,0 +1,36 @@
'use strict';
// Refs: https://github.com/nodejs/node/issues/52663
const common = require('../common');
const assert = require('node:assert');
const fs = require('node:fs');
const path = require('node:path');
if (!common.canCreateSymLink())
common.skip('insufficient privileges');
const tmpdir = require('../common/tmpdir');
const readdirDir = tmpdir.path;
// clean up the tmpdir
tmpdir.refresh();
// a/1, a/2
const a = path.join(readdirDir, 'a');
fs.mkdirSync(a);
fs.writeFileSync(path.join(a, '1'), 'irrelevant');
fs.writeFileSync(path.join(a, '2'), 'irrelevant');
// b/1
const b = path.join(readdirDir, 'b');
fs.mkdirSync(b);
fs.writeFileSync(path.join(b, '1'), 'irrelevant');
// b/c -> a
const c = path.join(readdirDir, 'b', 'c');
fs.symlinkSync(a, c, 'dir');
// Just check that the number of entries are the same
assert.strictEqual(
fs.readdirSync(b, { recursive: true, withFileTypes: true }).length,
fs.readdirSync(b, { recursive: true, withFileTypes: false }).length
);

View File

@@ -1,53 +0,0 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
// This tests that the http2 server sends data early when it accumulates
// enough from ongoing requests to avoid DoS as mitigation for
// CVE-2019-9517 and CVE-2019-9511.
// Added by https://github.com/nodejs/node/commit/8a4a193
const fixtures = require('../common/fixtures');
const assert = require('assert');
const http2 = require('http2');
const content = fixtures.readSync('person-large.jpg');
const server = http2.createServer({
maxSessionMemory: 1000
});
let streamCount = 0;
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'image/jpeg',
':status': 200
});
stream.end(content);
console.log('server sends content', ++streamCount);
});
server.listen(0, common.mustCall(() => {
const client = http2.connect(`http://localhost:${server.address().port}/`);
let endCount = 0;
let finished = 0;
for (let i = 0; i < 100; i++) {
const req = client.request({ ':path': '/' }).end();
const chunks = [];
req.on('data', (chunk) => {
chunks.push(chunk);
});
req.on('end', common.mustCall(() => {
console.log('client receives content', ++endCount);
assert.deepStrictEqual(Buffer.concat(chunks), content);
if (++finished === 100) {
client.close();
server.close();
}
}));
req.on('error', (e) => {
console.log('client error', e);
});
}
}));

View File

@@ -0,0 +1,96 @@
'use strict';
const common = require('../common');
const net = require('net');
const assert = require('assert');
const server = net.createServer();
const { getEventListeners, once } = require('events');
const liveConnections = new Set();
server.listen(0, common.mustCall(async () => {
const port = server.address().port;
const host = 'localhost';
const socketOptions = (signal) => ({ port, host, signal });
server.on('connection', (connection) => {
liveConnections.add(connection);
connection.on('close', () => {
liveConnections.delete(connection);
});
});
const assertAbort = async (socket, testName) => {
try {
await once(socket, 'close');
assert.fail(`close ${testName} should have thrown`);
} catch (err) {
assert.strictEqual(err.name, 'AbortError');
}
};
async function postAbort() {
const ac = new AbortController();
const { signal } = ac;
const socket = net.connect(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
ac.abort();
await assertAbort(socket, 'postAbort');
}
async function preAbort() {
const ac = new AbortController();
const { signal } = ac;
ac.abort();
const socket = net.connect(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 0);
await assertAbort(socket, 'preAbort');
}
async function tickAbort() {
const ac = new AbortController();
const { signal } = ac;
setImmediate(() => ac.abort());
const socket = net.connect(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
await assertAbort(socket, 'tickAbort');
}
async function testConstructor() {
const ac = new AbortController();
const { signal } = ac;
ac.abort();
const socket = new net.Socket(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 0);
await assertAbort(socket, 'testConstructor');
}
async function testConstructorPost() {
const ac = new AbortController();
const { signal } = ac;
const socket = new net.Socket(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
ac.abort();
await assertAbort(socket, 'testConstructorPost');
}
async function testConstructorPostTick() {
const ac = new AbortController();
const { signal } = ac;
const socket = new net.Socket(socketOptions(signal));
assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
setImmediate(() => ac.abort());
await assertAbort(socket, 'testConstructorPostTick');
}
await postAbort();
await preAbort();
await tickAbort();
await testConstructor();
await testConstructorPost();
await testConstructorPostTick();
// Killing the net.socket without connecting hangs the server.
for (const connection of liveConnections) {
connection.destroy();
}
server.close(common.mustCall());
}));

View File

@@ -0,0 +1,21 @@
// Flags: --expose-internals
'use strict';
require('../common');
// This tests that the prototype accessors added by StreamBase::AddMethods
// are not enumerable. They could be enumerated when inspecting the prototype
// with util.inspect or the inspector protocol.
const assert = require('assert');
// Or anything that calls StreamBase::AddMethods when setting up its prototype
const { internalBinding } = require('internal/test/binding');
const TTY = internalBinding('tty_wrap').TTY;
{
const ttyIsEnumerable = Object.prototype.propertyIsEnumerable.bind(TTY);
assert.strictEqual(ttyIsEnumerable('bytesRead'), false);
assert.strictEqual(ttyIsEnumerable('fd'), false);
assert.strictEqual(ttyIsEnumerable('_externalStream'), false);
}

View File

@@ -0,0 +1,31 @@
'use strict';
const common = require('../common');
const assert = require('assert');
function timerNotCanceled() {
assert.fail('Timer should be canceled');
}
process.on(
'warning',
common.mustNotCall(() => {
assert.fail('Timer should be canceled');
})
);
{
const timeout = setTimeout(timerNotCanceled, 0);
clearTimeout(timeout);
}
{
const interval = setInterval(timerNotCanceled, 0);
clearInterval(interval);
}
{
const timeout = setTimeout(timerNotCanceled, 0);
timeout.refresh();
clearTimeout(timeout);
}