mirror of
https://github.com/oven-sh/bun
synced 2026-02-06 17:08:51 +00:00
Compare commits
11 Commits
dylan/pyth
...
nektro-pat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70ce4d2006 | ||
|
|
b2b245832a | ||
|
|
b771fe2414 | ||
|
|
c67766797f | ||
|
|
bfdc0b78c7 | ||
|
|
83656c15b3 | ||
|
|
dff1d3d73a | ||
|
|
c6803990cd | ||
|
|
e4adeb1939 | ||
|
|
3b88c66a55 | ||
|
|
45bc34edcd |
@@ -16,6 +16,7 @@
|
||||
#include "JavaScriptCore/JSType.h"
|
||||
#include "JavaScriptCore/Symbol.h"
|
||||
#include "wtf/Assertions.h"
|
||||
#include "wtf/Vector.h"
|
||||
#include "wtf/text/ASCIIFastPath.h"
|
||||
#include "wtf/text/ASCIILiteral.h"
|
||||
#include "wtf/text/MakeString.h"
|
||||
@@ -350,12 +351,60 @@ extern "C" BunString Bun__ErrorCode__determineSpecificType(JSC::JSGlobalObject*
|
||||
|
||||
namespace Message {
|
||||
|
||||
void addList(WTF::StringBuilder& result, WTF::Vector<WTF::String>& types)
|
||||
{
|
||||
switch (types.size()) {
|
||||
case 0:
|
||||
return;
|
||||
case 1:
|
||||
result.append(types.at(0));
|
||||
return;
|
||||
case 2:
|
||||
result.append(types.at(0));
|
||||
result.append(" or "_s);
|
||||
result.append(types.at(1));
|
||||
return;
|
||||
case 3:
|
||||
result.append(types.at(0));
|
||||
result.append(", "_s);
|
||||
result.append(types.at(1));
|
||||
result.append(", or "_s);
|
||||
result.append(types.at(2));
|
||||
return;
|
||||
default: {
|
||||
for (unsigned i = 0; i < types.size() - 1; i++) {
|
||||
result.append(types.at(i));
|
||||
result.append(", "_s);
|
||||
}
|
||||
result.append("or "_s);
|
||||
result.append(types.at(types.size() - 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, const StringView& expected_type, JSValue actual_value)
|
||||
{
|
||||
auto actual_value_string = determineSpecificType(globalObject, actual_value);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
return makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received "_s, actual_value_string);
|
||||
auto ty_first_char = expected_type[0];
|
||||
WTF::StringBuilder result;
|
||||
result.append("The "_s);
|
||||
|
||||
if (arg_name.endsWith(" argument"_s)) {
|
||||
result.append(arg_name);
|
||||
} else {
|
||||
result.append("\""_s);
|
||||
result.append(arg_name);
|
||||
result.append("\" "_s);
|
||||
result.append(arg_name.contains('.') ? "property"_s : "argument"_s);
|
||||
}
|
||||
result.append(" must be "_s);
|
||||
result.append(ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of "_s : "of type "_s);
|
||||
result.append(expected_type);
|
||||
result.append(". Received "_s, actual_value_string);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, ArgList expected_types, JSValue actual_value)
|
||||
@@ -372,25 +421,32 @@ WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* gl
|
||||
} else {
|
||||
result.append("\""_s);
|
||||
result.append(arg_name);
|
||||
result.append("\" argument"_s);
|
||||
result.append("\" "_s);
|
||||
result.append(arg_name.contains('.') ? "property"_s : "argument"_s);
|
||||
}
|
||||
result.append(" must be of type "_s);
|
||||
result.append(" must be "_s);
|
||||
|
||||
unsigned length = expected_types.size();
|
||||
if (length == 1) {
|
||||
result.append(expected_types.at(0).toWTFString(globalObject));
|
||||
} else if (length == 2) {
|
||||
result.append(expected_types.at(0).toWTFString(globalObject));
|
||||
result.append(" or "_s);
|
||||
result.append(expected_types.at(1).toWTFString(globalObject));
|
||||
} else {
|
||||
for (unsigned i = 0; i < length - 1; i++) {
|
||||
JSValue expected_type = expected_types.at(i);
|
||||
result.append(expected_type.toWTFString(globalObject));
|
||||
result.append(", "_s);
|
||||
}
|
||||
result.append("or "_s);
|
||||
result.append(expected_types.at(length - 1).toWTFString(globalObject));
|
||||
WTF::Vector<WTF::String> types;
|
||||
WTF::Vector<WTF::String> instances;
|
||||
for (unsigned i = 0; i < expected_types.size(); i++) {
|
||||
auto ty_str = expected_types.at(i).toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
auto ty_first_char = ty_str[0];
|
||||
if (ty_first_char >= 'A' && ty_first_char <= 'Z')
|
||||
instances.append(ty_str);
|
||||
else
|
||||
types.append(ty_str);
|
||||
}
|
||||
|
||||
if (types.size() > 0) {
|
||||
result.append(types.size() > 1 ? "one of type "_s : "of type "_s);
|
||||
addList(result, types);
|
||||
if (instances.size() > 0) result.append(" or "_s);
|
||||
}
|
||||
|
||||
if (instances.size() > 0) {
|
||||
result.append("an instance of "_s);
|
||||
addList(result, instances);
|
||||
}
|
||||
|
||||
result.append(". Received "_s, actual_value_string);
|
||||
@@ -440,14 +496,8 @@ namespace ERR {
|
||||
|
||||
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value)
|
||||
{
|
||||
auto arg_kind = arg_name.contains('.') ? "property"_s : "argument"_s;
|
||||
auto ty_first_char = expected_type[0];
|
||||
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;
|
||||
|
||||
auto actual_value = determineSpecificType(globalObject, val_actual_value);
|
||||
auto message = Message::ERR_INVALID_ARG_TYPE(throwScope, globalObject, arg_name, expected_type, val_actual_value);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
|
||||
auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
|
||||
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message));
|
||||
return {};
|
||||
}
|
||||
@@ -455,15 +505,9 @@ JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalO
|
||||
{
|
||||
auto arg_name = val_arg_name.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
auto arg_kind = arg_name.contains('.') ? "property"_s : "argument"_s;
|
||||
|
||||
auto ty_first_char = expected_type[0];
|
||||
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;
|
||||
|
||||
auto actual_value = determineSpecificType(globalObject, val_actual_value);
|
||||
auto message = Message::ERR_INVALID_ARG_TYPE(throwScope, globalObject, arg_name, expected_type, val_actual_value);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
|
||||
auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
|
||||
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message));
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ const string = bun.string;
|
||||
const Output = bun.Output;
|
||||
const ZigString = JSC.ZigString;
|
||||
const uv = bun.windows.libuv;
|
||||
const validators = @import("./util/validators.zig");
|
||||
const envloader = @import("./../../env_loader.zig");
|
||||
|
||||
pub fn internalErrorName(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
|
||||
const arguments = callframe.arguments_old(1).slice();
|
||||
@@ -212,3 +214,24 @@ pub fn normalizeEncoding(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFr
|
||||
if (str.inMapCaseInsensitive(JSC.Node.Encoding.map)) |enc| return enc.toJS(globalThis);
|
||||
return JSC.JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn parseEnv(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue {
|
||||
const content = callframe.argument(0);
|
||||
try validators.validateString(globalThis, content, "content", .{});
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(bun.default_allocator);
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
const str = content.asString().toSlice(globalThis, allocator);
|
||||
|
||||
var map = envloader.Map.init(allocator);
|
||||
var p = envloader.Loader.init(&map, allocator);
|
||||
p.loadFromString(str.slice(), true, false);
|
||||
|
||||
var obj = JSC.JSValue.createEmptyObject(globalThis, map.map.count());
|
||||
for (map.map.keys(), map.map.values()) |k, v| {
|
||||
obj.put(globalThis, JSC.ZigString.initUTF8(k), bun.String.createUTF8ForJS(globalThis, v.value));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -538,9 +538,9 @@ pub const Loader = struct {
|
||||
}
|
||||
|
||||
// mostly for tests
|
||||
pub fn loadFromString(this: *Loader, str: string, comptime overwrite: bool) void {
|
||||
pub fn loadFromString(this: *Loader, str: string, comptime overwrite: bool, comptime expand: bool) void {
|
||||
var source = logger.Source.initPathString("test", str);
|
||||
Parser.parse(&source, this.allocator, this.map, overwrite, false);
|
||||
Parser.parse(&source, this.allocator, this.map, overwrite, false, expand);
|
||||
std.mem.doNotOptimizeAway(&source);
|
||||
}
|
||||
|
||||
@@ -803,6 +803,7 @@ pub const Loader = struct {
|
||||
this.map,
|
||||
override,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
@field(this, base) = source;
|
||||
@@ -873,6 +874,7 @@ pub const Loader = struct {
|
||||
this.map,
|
||||
override,
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
try this.custom_files_loaded.put(file_path, source);
|
||||
@@ -1097,6 +1099,7 @@ const Parser = struct {
|
||||
map: *Map,
|
||||
comptime override: bool,
|
||||
comptime is_process: bool,
|
||||
comptime expand: bool,
|
||||
) void {
|
||||
var count = map.map.count();
|
||||
while (this.pos < this.src.len) {
|
||||
@@ -1120,7 +1123,7 @@ const Parser = struct {
|
||||
.conditional = false,
|
||||
};
|
||||
}
|
||||
if (comptime !is_process) {
|
||||
if (comptime !is_process and expand) {
|
||||
var it = map.iterator();
|
||||
while (it.next()) |entry| {
|
||||
if (count > 0) {
|
||||
@@ -1142,9 +1145,10 @@ const Parser = struct {
|
||||
map: *Map,
|
||||
comptime override: bool,
|
||||
comptime is_process: bool,
|
||||
comptime expand: bool,
|
||||
) void {
|
||||
var parser = Parser{ .src = source.contents };
|
||||
parser._parse(allocator, map, override, is_process);
|
||||
parser._parse(allocator, map, override, is_process, expand);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
const { validateFunction } = require("internal/validators");
|
||||
|
||||
const ArrayPrototypePush = Array.prototype.push;
|
||||
|
||||
const kCustomPromisifiedSymbol = Symbol.for("nodejs.util.promisify.custom");
|
||||
const kCustomPromisifyArgsSymbol = Symbol("customPromisifyArgs");
|
||||
|
||||
@@ -18,55 +22,74 @@ function defineCustomPromisifyArgs(target, args) {
|
||||
return args;
|
||||
}
|
||||
|
||||
var promisify = function promisify(original) {
|
||||
if (typeof original !== "function") throw new TypeError('The "original" argument must be of type Function');
|
||||
const custom = original[kCustomPromisifiedSymbol];
|
||||
if (custom) {
|
||||
if (typeof custom !== "function") {
|
||||
throw new TypeError('The "util.promisify.custom" argument must be of type Function');
|
||||
}
|
||||
// ensure that we don't create another promisified function wrapper
|
||||
return defineCustomPromisify(custom, custom);
|
||||
function promisify(original) {
|
||||
validateFunction(original, "original");
|
||||
|
||||
if (original[kCustomPromisifiedSymbol]) {
|
||||
const fn = original[kCustomPromisifiedSymbol];
|
||||
|
||||
validateFunction(fn, "util.promisify.custom");
|
||||
|
||||
Object.defineProperty(fn, kCustomPromisifiedSymbol, {
|
||||
__proto__: null,
|
||||
value: fn,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
});
|
||||
Object.defineProperty(fn, "name", { value: original.name });
|
||||
return fn;
|
||||
}
|
||||
|
||||
const callbackArgs = original[kCustomPromisifyArgsSymbol];
|
||||
function fn(...originalArgs) {
|
||||
const { promise, resolve, reject } = Promise.withResolvers();
|
||||
try {
|
||||
original.$apply(this, [
|
||||
...originalArgs,
|
||||
function (err, ...values) {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
// Names to create an object from in case the callback receives multiple
|
||||
// arguments, e.g. ['bytesRead', 'buffer'] for fs.read.
|
||||
const argumentNames = original[kCustomPromisifyArgsSymbol];
|
||||
|
||||
if (callbackArgs !== undefined) {
|
||||
// if (!Array.isArray(callbackArgs)) {
|
||||
// throw new TypeError('The "customPromisifyArgs" argument must be of type Array');
|
||||
// }
|
||||
// if (callbackArgs.length !== values.length) {
|
||||
// throw new Error("Mismatched length in promisify callback args");
|
||||
// }
|
||||
const result = {};
|
||||
for (let i = 0; i < callbackArgs.length; i++) {
|
||||
result[callbackArgs[i]] = values[i];
|
||||
}
|
||||
resolve(result);
|
||||
} else {
|
||||
resolve(values[0]);
|
||||
}
|
||||
},
|
||||
]);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
return promise;
|
||||
function fn(...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ArrayPrototypePush.$call(args, (err, ...values) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
if (argumentNames !== undefined && values.length > 1) {
|
||||
const obj = {};
|
||||
for (let i = 0; i < argumentNames.length; i++) obj[argumentNames[i]] = values[i];
|
||||
resolve(obj);
|
||||
} else {
|
||||
resolve(values[0]);
|
||||
}
|
||||
});
|
||||
if ($isPromise(original.$apply(this, args))) {
|
||||
process.emitWarning(
|
||||
"Calling promisify on a function that returns a Promise is likely a mistake.",
|
||||
"DeprecationWarning",
|
||||
"DEP0174",
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
|
||||
defineCustomPromisify(fn, fn);
|
||||
return Object.defineProperties(fn, Object.getOwnPropertyDescriptors(original));
|
||||
};
|
||||
|
||||
Object.defineProperty(fn, kCustomPromisifiedSymbol, {
|
||||
__proto__: null,
|
||||
value: fn,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
const descriptors = Object.getOwnPropertyDescriptors(original);
|
||||
const propertiesValues = Object.values(descriptors);
|
||||
for (let i = 0; i < propertiesValues.length; i++) {
|
||||
// We want to use null-prototype objects to not rely on globally mutable
|
||||
// %Object.prototype%.
|
||||
Object.setPrototypeOf(propertiesValues[i], null);
|
||||
}
|
||||
Object.defineProperties(fn, descriptors);
|
||||
Object.defineProperty(fn, "name", { value: original.name });
|
||||
return fn;
|
||||
}
|
||||
promisify.custom = kCustomPromisifiedSymbol;
|
||||
|
||||
// Lazily load node:timers/promises promisified functions onto the global timers.
|
||||
|
||||
@@ -71,7 +71,9 @@ Stream.pipeline = pipeline;
|
||||
const { addAbortSignal } = require("internal/streams/add-abort-signal");
|
||||
Stream.addAbortSignal = addAbortSignal;
|
||||
Stream.finished = eos;
|
||||
Object.defineProperty(Stream.finished, "name", { value: "finished" });
|
||||
Stream.destroy = destroyer;
|
||||
Object.defineProperty(Stream.destroy, "name", { value: "destroy" });
|
||||
Stream.compose = compose;
|
||||
Stream.setDefaultHighWaterMark = setDefaultHighWaterMark;
|
||||
Stream.getDefaultHighWaterMark = getDefaultHighWaterMark;
|
||||
|
||||
@@ -53,12 +53,11 @@ function warnOnDeactivatedColors(env) {
|
||||
}
|
||||
}
|
||||
|
||||
function getColorDepth(env: NodeJS.ProcessEnv) {
|
||||
const FORCE_COLOR = env.FORCE_COLOR;
|
||||
function getColorDepth(env: NodeJS.ProcessEnv = process.env) {
|
||||
// Use level 0-3 to support the same levels as `chalk` does. This is done for
|
||||
// consistency throughout the ecosystem.
|
||||
if (FORCE_COLOR !== undefined) {
|
||||
switch (FORCE_COLOR) {
|
||||
if (env.FORCE_COLOR !== undefined) {
|
||||
switch (env.FORCE_COLOR) {
|
||||
case "":
|
||||
case "1":
|
||||
case "true":
|
||||
@@ -121,14 +120,13 @@ function getColorDepth(env: NodeJS.ProcessEnv) {
|
||||
return COLORS_2;
|
||||
}
|
||||
|
||||
const TEAMCITY_VERSION = env.TEAMCITY_VERSION;
|
||||
if (TEAMCITY_VERSION) {
|
||||
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(TEAMCITY_VERSION) ? COLORS_16 : COLORS_2;
|
||||
if ("TEAMCITY_VERSION" in env) {
|
||||
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.exec(env.TEAMCITY_VERSION) !== null ? COLORS_16 : COLORS_2;
|
||||
}
|
||||
|
||||
switch (env.TERM_PROGRAM) {
|
||||
case "iTerm.app":
|
||||
if (!env.TERM_PROGRAM_VERSION || /^[0-2]\./.test(env.TERM_PROGRAM_VERSION)) {
|
||||
if (!env.TERM_PROGRAM_VERSION || /^[0-2]\./.exec(env.TERM_PROGRAM_VERSION) !== null) {
|
||||
return COLORS_256;
|
||||
}
|
||||
return COLORS_16m;
|
||||
@@ -141,25 +139,21 @@ function getColorDepth(env: NodeJS.ProcessEnv) {
|
||||
return COLORS_256;
|
||||
}
|
||||
|
||||
const COLORTERM = env.COLORTERM;
|
||||
|
||||
if (COLORTERM === "truecolor" || COLORTERM === "24bit") {
|
||||
if (env.COLORTERM === "truecolor" || env.COLORTERM === "24bit") {
|
||||
return COLORS_16m;
|
||||
}
|
||||
|
||||
const TERM = env.TERM;
|
||||
|
||||
if (TERM) {
|
||||
if (/^xterm-256/.test(TERM) !== null) {
|
||||
if (env.TERM) {
|
||||
if (/^xterm-256/.exec(env.TERM) !== null) {
|
||||
return COLORS_256;
|
||||
}
|
||||
|
||||
const termEnv = TERM.toLowerCase();
|
||||
const termEnv = env.TERM.toLowerCase();
|
||||
|
||||
if (TERM_ENVS[termEnv]) {
|
||||
return TERM_ENVS[termEnv];
|
||||
}
|
||||
if (TERM_ENVS_REG_EXP.some(term => term.test(termEnv))) {
|
||||
if (TERM_ENVS_REG_EXP.some(term => term.exec(termEnv) !== null)) {
|
||||
return COLORS_16;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
const isInsideNodeModules: () => boolean = $newZigFunction("node_util_binding.zig", "isInsideNodeModules", 0);
|
||||
const isInsideNodeModules = $newZigFunction("node_util_binding.zig", "isInsideNodeModules", 0);
|
||||
|
||||
function shouldColorize(stream) {
|
||||
if (process.env.FORCE_COLOR !== undefined) {
|
||||
return require("internal/tty").getColorDepth() > 2;
|
||||
}
|
||||
return stream?.isTTY && (typeof stream.getColorDepth === "function" ? stream.getColorDepth() > 2 : true);
|
||||
}
|
||||
|
||||
export default {
|
||||
isInsideNodeModules,
|
||||
shouldColorize,
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ const {
|
||||
validateString,
|
||||
validateBoolean,
|
||||
validateNumber,
|
||||
validateInt32,
|
||||
} = require("internal/validators");
|
||||
|
||||
const errorCodes = {
|
||||
@@ -346,19 +347,14 @@ function validateResolverOptions(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of ["timeout", "tries"]) {
|
||||
if (key in options) {
|
||||
if (typeof options[key] !== "number") {
|
||||
throw $ERR_INVALID_ARG_TYPE(key, "number", options[key]);
|
||||
}
|
||||
}
|
||||
{
|
||||
const { timeout = -1 } = options;
|
||||
validateInt32(timeout, "options.timeout", -1);
|
||||
}
|
||||
|
||||
if ("timeout" in options) {
|
||||
const timeout = options.timeout;
|
||||
if ((timeout < 0 && timeout != -1) || Math.floor(timeout) != timeout || timeout >= 2 ** 31) {
|
||||
throw $ERR_OUT_OF_RANGE("Invalid timeout", timeout);
|
||||
}
|
||||
{
|
||||
const { tries = 4 } = { ...options };
|
||||
validateInt32(tries, "options.tries", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ const types = require("node:util/types");
|
||||
/** @type {import('node-inspect-extracted')} */
|
||||
const utl = require("internal/util/inspect");
|
||||
const { promisify } = require("internal/promisify");
|
||||
const { validateString, validateOneOf } = require("internal/validators");
|
||||
const { validateString, validateOneOf, validateBoolean } = require("internal/validators");
|
||||
const { isReadableStream, isWritableStream, isNodeStream } = require("internal/streams/utils");
|
||||
|
||||
const internalErrorName = $newZigFunction("node_util_binding.zig", "internalErrorName", 1);
|
||||
const parseEnv = $newZigFunction("node_util_binding.zig", "parseEnv", 1);
|
||||
|
||||
const NumberIsSafeInteger = Number.isSafeInteger;
|
||||
const ObjectKeys = Object.keys;
|
||||
@@ -233,8 +235,15 @@ var toUSVString = input => {
|
||||
return (input + "").toWellFormed();
|
||||
};
|
||||
|
||||
function styleText(format, text) {
|
||||
function styleText(format, text, { validateStream = true, stream = process.stdout } = {}) {
|
||||
validateString(text, "text");
|
||||
validateBoolean(validateStream, "options.validateStream");
|
||||
|
||||
if (validateStream) {
|
||||
if (!isReadableStream(stream) && !isWritableStream(stream) && !isNodeStream(stream)) {
|
||||
throw $ERR_INVALID_ARG_TYPE("stream", ["ReadableStream", "WritableStream", "Stream"], stream);
|
||||
}
|
||||
}
|
||||
|
||||
if ($isJSArray(format)) {
|
||||
let left = "";
|
||||
@@ -251,11 +260,15 @@ function styleText(format, text) {
|
||||
return `${left}${text}${right}`;
|
||||
}
|
||||
|
||||
let formatCodes = inspect.colors[format];
|
||||
|
||||
const formatCodes = inspect.colors[format];
|
||||
if (formatCodes == null) {
|
||||
validateOneOf(format, "format", ObjectKeys(inspect.colors));
|
||||
}
|
||||
|
||||
if (validateStream && (!stream || !require("internal/util").shouldColorize(stream))) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return `\u001b[${formatCodes[0]}m${text}\u001b[${formatCodes[1]}m`;
|
||||
}
|
||||
|
||||
@@ -347,7 +360,7 @@ cjs_exports = {
|
||||
// transferableAbortController,
|
||||
aborted,
|
||||
types,
|
||||
// parseEnv,
|
||||
parseEnv,
|
||||
parseArgs,
|
||||
TextDecoder,
|
||||
TextEncoder,
|
||||
|
||||
@@ -657,7 +657,7 @@ describe("fork", () => {
|
||||
code: "ERR_INVALID_ARG_TYPE",
|
||||
name: "TypeError",
|
||||
message: expect.stringContaining(
|
||||
`The "modulePath" argument must be of type string, Buffer, or URL. Received `,
|
||||
`The "modulePath" argument must be of type string or an instance of Buffer or URL. Received `,
|
||||
),
|
||||
}),
|
||||
);
|
||||
|
||||
1
test/js/node/test/fixtures/dotenv/valid.env
vendored
1
test/js/node/test/fixtures/dotenv/valid.env
vendored
@@ -38,6 +38,7 @@ RETAIN_INNER_QUOTES={"foo": "bar"}
|
||||
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
|
||||
RETAIN_INNER_QUOTES_AS_BACKTICKS=`{"foo": "bar's"}`
|
||||
TRIM_SPACE_FROM_UNQUOTED= some spaced out string
|
||||
SPACE_BEFORE_DOUBLE_QUOTES= "space before double quotes"
|
||||
EMAIL=therealnerdybeast@example.tld
|
||||
SPACED_KEY = parsed
|
||||
EDGE_CASE_INLINE_COMMENTS="VALUE1" # or "VALUE2" or "VALUE3"
|
||||
|
||||
@@ -35,7 +35,8 @@ function checkArgs(connected) {
|
||||
{
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "buffer" argument must be of type string, Buffer, TypedArray, or DataView. Received undefined'
|
||||
message: 'The "buffer" argument must be of type string or an instance ' +
|
||||
'of Buffer, TypedArray, or DataView. Received undefined'
|
||||
}
|
||||
);
|
||||
|
||||
@@ -129,7 +130,8 @@ function checkArgs(connected) {
|
||||
{
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "buffer" argument must be of type string, Buffer, TypedArray, or DataView. Received type number (23)'
|
||||
message: 'The "buffer" argument must be of type string or an instance ' +
|
||||
'of Buffer, TypedArray, or DataView. Received type number (23)'
|
||||
}
|
||||
);
|
||||
|
||||
@@ -139,7 +141,8 @@ function checkArgs(connected) {
|
||||
{
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "buffer list arguments" argument must be of type string, Buffer, TypedArray, or DataView. ' +
|
||||
message: 'The "buffer list arguments" argument must be of type string ' +
|
||||
'or an instance of Buffer, TypedArray, or DataView. ' +
|
||||
'Received an instance of Array'
|
||||
}
|
||||
);
|
||||
|
||||
@@ -17,13 +17,23 @@ for (const ctor of [dns.Resolver, dns.promises.Resolver]) {
|
||||
assert.throws(() => new ctor({ timeout }), {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: `The "options.timeout" property must be of type number.` + common.invalidArgTypeHelper(timeout),
|
||||
});
|
||||
}
|
||||
|
||||
for (const timeout of [-2, 4.2, 2 ** 31]) {
|
||||
for (const timeout of [4.2]) {
|
||||
assert.throws(() => new ctor({ timeout }), {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
name: 'RangeError',
|
||||
message: `The value of "options.timeout" is out of range. It must be an integer. Received ${timeout}`,
|
||||
});
|
||||
}
|
||||
|
||||
for (const timeout of [-2, 2 ** 31]) {
|
||||
assert.throws(() => new ctor({ timeout }), {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
name: 'RangeError',
|
||||
message: `The value of "options.timeout" is out of range. It must be >= -1 and <= 2147483647. Received ${timeout}`,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,6 @@ assert.throws(
|
||||
() => recurse(),
|
||||
{
|
||||
name: 'RangeError',
|
||||
// message: 'Maximum call stack size exceeded'
|
||||
message: 'Maximum call stack size exceeded.'
|
||||
}
|
||||
);
|
||||
|
||||
@@ -225,6 +225,7 @@ const values = [
|
||||
const errLines = stderr.trim().split(/[\r\n]+/);
|
||||
const errLine = errLines.find((l) => /^error/.exec(l));
|
||||
assert.strictEqual(errLine, `error: ${fixture}`);
|
||||
assert.strictEqual(errLines.length, 10);
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -274,6 +275,8 @@ const values = [
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The last argument must be of type function.' +
|
||||
common.invalidArgTypeHelper(value)
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -287,6 +290,7 @@ const values = [
|
||||
const cbPromiseFn = callbackify(promiseFn);
|
||||
|
||||
cbPromiseFn(null, (err) => {
|
||||
assert.strictEqual(err.message, 'Promise was rejected with a falsy value');
|
||||
assert.strictEqual(err.code, 'ERR_FALSY_VALUE_REJECTION');
|
||||
assert.strictEqual(err.reason, null);
|
||||
// skipped, bun doesn't hide callbackifyOnRejected from the stack trace
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
'use strict';
|
||||
// emitExperimentalWarning is a node internal not used by bun, so this test is skipped
|
||||
|
||||
// // Flags: --expose-internals
|
||||
// const common = require('../common');
|
||||
// const assert = require('assert');
|
||||
// const { emitExperimentalWarning } = require('internal/util');
|
||||
|
||||
// This test ensures that the emitExperimentalWarning in internal/util emits a
|
||||
// warning when passed an unsupported feature and that it simply returns
|
||||
// when passed the same feature multiple times.
|
||||
|
||||
// process.on('warning', common.mustCall((warning) => {
|
||||
// assert.match(warning.message, /is an experimental feature/);
|
||||
// }, 2));
|
||||
|
||||
// emitExperimentalWarning('feature1');
|
||||
// emitExperimentalWarning('feature1'); // should not warn
|
||||
// emitExperimentalWarning('feature2');
|
||||
@@ -88,6 +88,8 @@ assert.throws(() => {
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "superCtor.prototype" property must be of type object. ' +
|
||||
'Received undefined'
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
@@ -95,6 +97,8 @@ assert.throws(() => {
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "superCtor" argument must be of type function. ' +
|
||||
'Received null'
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
@@ -102,4 +106,5 @@ assert.throws(() => {
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "ctor" argument must be of type function. Received null'
|
||||
});
|
||||
|
||||
70
test/js/node/test/parallel/test-util-parse-env.js
Normal file
70
test/js/node/test/parallel/test-util-parse-env.js
Normal file
@@ -0,0 +1,70 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const fixtures = require('../../test/common/fixtures');
|
||||
const assert = require('node:assert');
|
||||
const util = require('node:util');
|
||||
const fs = require('node:fs');
|
||||
|
||||
{
|
||||
const validEnvFilePath = fixtures.path('dotenv/valid.env');
|
||||
const validContent = fs.readFileSync(validEnvFilePath, 'utf8');
|
||||
|
||||
assert.deepStrictEqual(util.parseEnv(validContent), {
|
||||
AFTER_LINE: 'after_line',
|
||||
BACKTICKS: 'backticks',
|
||||
BACKTICKS_INSIDE_DOUBLE: '`backticks` work inside double quotes',
|
||||
BACKTICKS_INSIDE_SINGLE: '`backticks` work inside single quotes',
|
||||
BACKTICKS_SPACED: ' backticks ',
|
||||
BASIC: 'basic',
|
||||
DONT_EXPAND_SQUOTED: 'dontexpand\\nnewlines',
|
||||
DONT_EXPAND_UNQUOTED: 'dontexpand\\nnewlines',
|
||||
DOUBLE_AND_SINGLE_QUOTES_INSIDE_BACKTICKS: "double \"quotes\" and single 'quotes' work inside backticks",
|
||||
DOUBLE_QUOTES: 'double_quotes',
|
||||
DOUBLE_QUOTES_INSIDE_BACKTICKS: 'double "quotes" work inside backticks',
|
||||
DOUBLE_QUOTES_INSIDE_SINGLE: 'double "quotes" work inside single quotes',
|
||||
DOUBLE_QUOTES_SPACED: ' double quotes ',
|
||||
DOUBLE_QUOTES_WITH_NO_SPACE_BRACKET: '{ port: $MONGOLAB_PORT}',
|
||||
EDGE_CASE_INLINE_COMMENTS: 'VALUE1',
|
||||
EMAIL: 'therealnerdybeast@example.tld',
|
||||
EMPTY: '',
|
||||
EMPTY_BACKTICKS: '',
|
||||
EMPTY_DOUBLE_QUOTES: '',
|
||||
EMPTY_SINGLE_QUOTES: '',
|
||||
EQUAL_SIGNS: 'equals==',
|
||||
EXPORT_EXAMPLE: 'ignore export',
|
||||
EXPAND_NEWLINES: 'expand\nnew\nlines',
|
||||
INLINE_COMMENTS: 'inline comments',
|
||||
INLINE_COMMENTS_BACKTICKS: 'inline comments outside of #backticks',
|
||||
INLINE_COMMENTS_DOUBLE_QUOTES: 'inline comments outside of #doublequotes',
|
||||
INLINE_COMMENTS_SINGLE_QUOTES: 'inline comments outside of #singlequotes',
|
||||
INLINE_COMMENTS_SPACE: 'inline comments start with a',
|
||||
MULTI_BACKTICKED: 'THIS\nIS\nA\n"MULTILINE\'S"\nSTRING',
|
||||
MULTI_DOUBLE_QUOTED: 'THIS\nIS\nA\nMULTILINE\nSTRING',
|
||||
MULTI_NOT_VALID: 'THIS',
|
||||
MULTI_NOT_VALID_QUOTE: '"',
|
||||
MULTI_SINGLE_QUOTED: 'THIS\nIS\nA\nMULTILINE\nSTRING',
|
||||
RETAIN_INNER_QUOTES: '{"foo": "bar"}',
|
||||
RETAIN_INNER_QUOTES_AS_BACKTICKS: '{"foo": "bar\'s"}',
|
||||
RETAIN_INNER_QUOTES_AS_STRING: '{"foo": "bar"}',
|
||||
SINGLE_QUOTES: 'single_quotes',
|
||||
SINGLE_QUOTES_INSIDE_BACKTICKS: "single 'quotes' work inside backticks",
|
||||
SINGLE_QUOTES_INSIDE_DOUBLE: "single 'quotes' work inside double quotes",
|
||||
SINGLE_QUOTES_SPACED: ' single quotes ',
|
||||
SPACED_KEY: 'parsed',
|
||||
SPACE_BEFORE_DOUBLE_QUOTES: 'space before double quotes',
|
||||
TRIM_SPACE_FROM_UNQUOTED: 'some spaced out string',
|
||||
});
|
||||
}
|
||||
|
||||
assert.deepStrictEqual(util.parseEnv(''), {});
|
||||
assert.deepStrictEqual(util.parseEnv('FOO=bar\nFOO=baz\n'), { FOO: 'baz' });
|
||||
|
||||
// Test for invalid input.
|
||||
assert.throws(() => {
|
||||
for (const value of [null, undefined, {}, []]) {
|
||||
util.parseEnv(value);
|
||||
}
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import '../common/index.mjs';
|
||||
import assert from 'node:assert';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
// Test that customly promisified methods in [util.promisify.custom]
|
||||
// have appropriate names
|
||||
|
||||
import fs from 'node:fs';
|
||||
import readline from 'node:readline';
|
||||
import stream from 'node:stream';
|
||||
import timers from 'node:timers';
|
||||
|
||||
|
||||
assert.strictEqual(
|
||||
promisify(fs.exists).name,
|
||||
'exists'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
promisify(readline.Interface.prototype.question).name,
|
||||
'question',
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
promisify(stream.finished).name,
|
||||
'finished'
|
||||
);
|
||||
assert.strictEqual(
|
||||
promisify(stream.pipeline).name,
|
||||
'pipeline'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
promisify(timers.setImmediate).name,
|
||||
'setImmediate'
|
||||
);
|
||||
assert.strictEqual(
|
||||
promisify(timers.setTimeout).name,
|
||||
'setTimeout'
|
||||
);
|
||||
215
test/js/node/test/parallel/test-util-promisify.js
Normal file
215
test/js/node/test/parallel/test-util-promisify.js
Normal file
@@ -0,0 +1,215 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const vm = require('vm');
|
||||
const { promisify } = require('util');
|
||||
|
||||
{
|
||||
const warningHandler = common.mustNotCall();
|
||||
process.on('warning', warningHandler);
|
||||
function foo() {}
|
||||
foo.constructor = (async () => {}).constructor;
|
||||
promisify(foo);
|
||||
process.off('warning', warningHandler);
|
||||
}
|
||||
|
||||
common.expectWarning(
|
||||
'DeprecationWarning',
|
||||
'Calling promisify on a function that returns a Promise is likely a mistake.',
|
||||
'DEP0174');
|
||||
promisify(async (callback) => { callback(); })().then(common.mustCall(() => {
|
||||
// We must add the second `expectWarning` call in the `.then` handler, when
|
||||
// the first warning has already been triggered.
|
||||
common.expectWarning(
|
||||
'DeprecationWarning',
|
||||
'Calling promisify on a function that returns a Promise is likely a mistake.',
|
||||
'DEP0174');
|
||||
promisify(async () => {})().then(common.mustNotCall());
|
||||
}));
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
|
||||
{
|
||||
const promise = stat(__filename);
|
||||
assert(promise instanceof Promise);
|
||||
promise.then(common.mustCall((value) => {
|
||||
assert.deepStrictEqual(value, fs.statSync(__filename));
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
const promise = stat('/dontexist');
|
||||
promise.catch(common.mustCall((error) => {
|
||||
assert(error.message.includes('ENOENT: no such file or directory, stat'));
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn() {}
|
||||
|
||||
function promisifedFn() {}
|
||||
fn[promisify.custom] = promisifedFn;
|
||||
assert.strictEqual(promisify(fn), promisifedFn);
|
||||
assert.strictEqual(promisify(promisify(fn)), promisifedFn);
|
||||
}
|
||||
|
||||
{
|
||||
function fn() {}
|
||||
|
||||
function promisifiedFn() {}
|
||||
|
||||
// util.promisify.custom is a shared symbol which can be accessed
|
||||
// as `Symbol.for("nodejs.util.promisify.custom")`.
|
||||
const kCustomPromisifiedSymbol = Symbol.for('nodejs.util.promisify.custom');
|
||||
fn[kCustomPromisifiedSymbol] = promisifiedFn;
|
||||
|
||||
assert.strictEqual(kCustomPromisifiedSymbol, promisify.custom);
|
||||
assert.strictEqual(promisify(fn), promisifiedFn);
|
||||
assert.strictEqual(promisify(promisify(fn)), promisifiedFn);
|
||||
}
|
||||
|
||||
{
|
||||
function fn() {}
|
||||
fn[promisify.custom] = 42;
|
||||
assert.throws(
|
||||
() => promisify(fn),
|
||||
{ code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const fn = vm.runInNewContext('(function() {})');
|
||||
assert.notStrictEqual(Object.getPrototypeOf(promisify(fn)),
|
||||
Function.prototype);
|
||||
}
|
||||
|
||||
{
|
||||
function fn(callback) {
|
||||
callback(null, 'foo', 'bar');
|
||||
}
|
||||
promisify(fn)().then(common.mustCall((value) => {
|
||||
assert.strictEqual(value, 'foo');
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn(callback) {
|
||||
callback(null);
|
||||
}
|
||||
promisify(fn)().then(common.mustCall((value) => {
|
||||
assert.strictEqual(value, undefined);
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn(callback) {
|
||||
callback();
|
||||
}
|
||||
promisify(fn)().then(common.mustCall((value) => {
|
||||
assert.strictEqual(value, undefined);
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn(err, val, callback) {
|
||||
callback(err, val);
|
||||
}
|
||||
promisify(fn)(null, 42).then(common.mustCall((value) => {
|
||||
assert.strictEqual(value, 42);
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn(err, val, callback) {
|
||||
callback(err, val);
|
||||
}
|
||||
promisify(fn)(new Error('oops'), null).catch(common.mustCall((err) => {
|
||||
assert.strictEqual(err.message, 'oops');
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
function fn(err, val, callback) {
|
||||
callback(err, val);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const value = await promisify(fn)(null, 42);
|
||||
assert.strictEqual(value, 42);
|
||||
})().then(common.mustCall());
|
||||
}
|
||||
|
||||
{
|
||||
const o = {};
|
||||
const fn = promisify(function(cb) {
|
||||
|
||||
cb(null, this === o);
|
||||
});
|
||||
|
||||
o.fn = fn;
|
||||
|
||||
o.fn().then(common.mustCall((val) => assert(val)));
|
||||
}
|
||||
|
||||
{
|
||||
const err = new Error('Should not have called the callback with the error.');
|
||||
const stack = err.stack;
|
||||
|
||||
const fn = promisify(function(cb) {
|
||||
cb(null);
|
||||
cb(err);
|
||||
});
|
||||
|
||||
(async () => {
|
||||
await fn();
|
||||
await Promise.resolve();
|
||||
return assert.strictEqual(stack, err.stack);
|
||||
})().then(common.mustCall());
|
||||
}
|
||||
|
||||
{
|
||||
function c() { }
|
||||
const a = promisify(function() { });
|
||||
const b = promisify(a);
|
||||
assert.notStrictEqual(c, a);
|
||||
assert.strictEqual(a, b);
|
||||
}
|
||||
|
||||
{
|
||||
let errToThrow;
|
||||
const thrower = promisify(function(a, b, c, cb) {
|
||||
errToThrow = new Error();
|
||||
throw errToThrow;
|
||||
});
|
||||
thrower(1, 2, 3)
|
||||
.then(assert.fail)
|
||||
.then(assert.fail, (e) => assert.strictEqual(e, errToThrow));
|
||||
}
|
||||
|
||||
{
|
||||
const err = new Error();
|
||||
|
||||
const a = promisify((cb) => cb(err))();
|
||||
const b = promisify(() => { throw err; })();
|
||||
|
||||
Promise.all([
|
||||
a.then(assert.fail, function(e) {
|
||||
assert.strictEqual(err, e);
|
||||
}),
|
||||
b.then(assert.fail, function(e) {
|
||||
assert.strictEqual(err, e);
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
[undefined, null, true, 0, 'str', {}, [], Symbol()].forEach((input) => {
|
||||
assert.throws(
|
||||
() => promisify(input),
|
||||
{
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: 'The "original" argument must be of type function.' +
|
||||
common.invalidArgTypeHelper(input)
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,12 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
const util = require('util');
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('node:assert');
|
||||
const util = require('node:util');
|
||||
const { WriteStream } = require('node:tty');
|
||||
|
||||
const styled = '\u001b[31mtest\u001b[39m';
|
||||
const noChange = 'test';
|
||||
|
||||
[
|
||||
undefined,
|
||||
@@ -31,13 +36,69 @@ assert.throws(() => {
|
||||
code: 'ERR_INVALID_ARG_VALUE',
|
||||
});
|
||||
|
||||
assert.strictEqual(util.styleText('red', 'test'), '\u001b[31mtest\u001b[39m');
|
||||
assert.strictEqual(
|
||||
util.styleText('red', 'test', { validateStream: false }),
|
||||
'\u001b[31mtest\u001b[39m',
|
||||
);
|
||||
|
||||
assert.strictEqual(util.styleText(['bold', 'red'], 'test'), '\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m');
|
||||
assert.strictEqual(util.styleText(['bold', 'red'], 'test'), util.styleText('bold', util.styleText('red', 'test')));
|
||||
assert.strictEqual(
|
||||
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
|
||||
'\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m',
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
|
||||
util.styleText(
|
||||
'bold',
|
||||
util.styleText('red', 'test', { validateStream: false }),
|
||||
{ validateStream: false },
|
||||
),
|
||||
);
|
||||
|
||||
assert.throws(() => {
|
||||
util.styleText(['invalid'], 'text');
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_VALUE',
|
||||
});
|
||||
|
||||
assert.throws(() => {
|
||||
util.styleText('red', 'text', { stream: {} });
|
||||
}, {
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
});
|
||||
|
||||
// does not throw
|
||||
util.styleText('red', 'text', { stream: {}, validateStream: false });
|
||||
|
||||
assert.strictEqual(
|
||||
util.styleText('red', 'test', { validateStream: false }),
|
||||
styled,
|
||||
);
|
||||
|
||||
const fd = common.getTTYfd();
|
||||
if (fd !== -1) {
|
||||
const writeStream = new WriteStream(fd);
|
||||
|
||||
const originalEnv = process.env;
|
||||
[
|
||||
{ isTTY: true, env: {}, expected: styled },
|
||||
{ isTTY: false, env: {}, expected: noChange },
|
||||
{ isTTY: true, env: { NODE_DISABLE_COLORS: '1' }, expected: noChange },
|
||||
{ isTTY: true, env: { NO_COLOR: '1' }, expected: noChange },
|
||||
{ isTTY: true, env: { FORCE_COLOR: '1' }, expected: styled },
|
||||
{ isTTY: true, env: { FORCE_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
|
||||
{ isTTY: false, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
|
||||
{ isTTY: true, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
|
||||
].forEach((testCase) => {
|
||||
writeStream.isTTY = testCase.isTTY;
|
||||
process.env = {
|
||||
...process.env,
|
||||
...testCase.env
|
||||
};
|
||||
const output = util.styleText('red', 'test', { stream: writeStream });
|
||||
assert.strictEqual(output, testCase.expected);
|
||||
process.env = originalEnv;
|
||||
});
|
||||
} else {
|
||||
common.skip('Could not create TTY fd');
|
||||
}
|
||||
|
||||
13
test/js/node/test/parallel/test-util-text-decoder.js
Normal file
13
test/js/node/test/parallel/test-util-text-decoder.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const assert = require('node:assert');
|
||||
|
||||
const latin1Bytes = new Uint8Array([0xc1, 0xe9, 0xf3]);
|
||||
|
||||
const expectedString = 'Áéó';
|
||||
|
||||
const decoder = new TextDecoder('windows-1252');
|
||||
const decodedString = decoder.decode(latin1Bytes);
|
||||
|
||||
assert.strictEqual(decodedString, expectedString);
|
||||
@@ -1,18 +1,10 @@
|
||||
'use strict';
|
||||
// JSStream is disabled because it is a node internal
|
||||
// vm tests are skipped because node:vm Module is not yet implemented
|
||||
// // Flags: --experimental-vm-modules --expose-internals
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const { types, inspect } = require('util');
|
||||
const vm = require('vm');
|
||||
// const { internalBinding } = require('internal/test/binding');
|
||||
// const { JSStream } = internalBinding('js_stream');
|
||||
|
||||
// const external = (new JSStream())._externalStream;
|
||||
|
||||
for (const [ value, _method ] of [
|
||||
// [ external, 'isExternal' ],
|
||||
[ new Date() ],
|
||||
[ (function() { return arguments; })(), 'isArgumentsObject' ],
|
||||
[ new Boolean(), 'isBooleanObject' ],
|
||||
@@ -277,14 +269,6 @@ for (const [ value, _method ] of [
|
||||
}
|
||||
}
|
||||
|
||||
// (skipped)
|
||||
// (async () => {
|
||||
// const m = new vm.SourceTextModule('');
|
||||
// await m.link(() => 0);
|
||||
// await m.evaluate();
|
||||
// assert.ok(types.isModuleNamespaceObject(m.namespace));
|
||||
// })().then(common.mustCall());
|
||||
|
||||
{
|
||||
// eslint-disable-next-line node-core/crypto-check
|
||||
if (common.hasCrypto) {
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
// Flags: --expose-internals
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const util = require('util');
|
||||
@@ -39,6 +38,68 @@ assert.strictEqual(util.isArray(/regexp/), false);
|
||||
assert.strictEqual(util.isArray(new Error()), false);
|
||||
assert.strictEqual(util.isArray({ __proto__: Array.prototype }), false);
|
||||
|
||||
// isRegExp
|
||||
assert.strictEqual(util.isRegExp(/regexp/), true);
|
||||
assert.strictEqual(util.isRegExp(RegExp(), 'foo'), true);
|
||||
assert.strictEqual(util.isRegExp(new RegExp()), true);
|
||||
assert.strictEqual(util.isRegExp(context('RegExp')()), true);
|
||||
assert.strictEqual(util.isRegExp({}), false);
|
||||
assert.strictEqual(util.isRegExp([]), false);
|
||||
assert.strictEqual(util.isRegExp(new Date()), false);
|
||||
assert.strictEqual(util.isRegExp({ __proto__: RegExp.prototype }), false);
|
||||
|
||||
// isDate
|
||||
assert.strictEqual(util.isDate(new Date()), true);
|
||||
assert.strictEqual(util.isDate(new Date(0), 'foo'), true);
|
||||
assert.strictEqual(util.isDate(new (context('Date'))()), true);
|
||||
assert.strictEqual(util.isDate(Date()), false);
|
||||
assert.strictEqual(util.isDate({}), false);
|
||||
assert.strictEqual(util.isDate([]), false);
|
||||
assert.strictEqual(util.isDate(new Error()), false);
|
||||
assert.strictEqual(util.isDate({ __proto__: Date.prototype }), false);
|
||||
|
||||
// isError
|
||||
assert.strictEqual(util.isError(new Error()), true);
|
||||
assert.strictEqual(util.isError(new TypeError()), true);
|
||||
assert.strictEqual(util.isError(new SyntaxError()), true);
|
||||
assert.strictEqual(util.isError(new (context('Error'))()), true);
|
||||
assert.strictEqual(util.isError(new (context('TypeError'))()), true);
|
||||
assert.strictEqual(util.isError(new (context('SyntaxError'))()), true);
|
||||
assert.strictEqual(util.isError({}), false);
|
||||
assert.strictEqual(util.isError({ name: 'Error', message: '' }), false);
|
||||
assert.strictEqual(util.isError([]), false);
|
||||
assert.strictEqual(util.isError({ __proto__: Error.prototype }), true);
|
||||
|
||||
// isObject
|
||||
assert.strictEqual(util.isObject({}), true);
|
||||
assert.strictEqual(util.isObject([]), true);
|
||||
assert.strictEqual(util.isObject(new Number(3)), true);
|
||||
assert.strictEqual(util.isObject(Number(4)), false);
|
||||
assert.strictEqual(util.isObject(1), false);
|
||||
|
||||
// isPrimitive
|
||||
assert.strictEqual(util.isPrimitive({}), false);
|
||||
assert.strictEqual(util.isPrimitive(new Error()), false);
|
||||
assert.strictEqual(util.isPrimitive(new Date()), false);
|
||||
assert.strictEqual(util.isPrimitive([]), false);
|
||||
assert.strictEqual(util.isPrimitive(/regexp/), false);
|
||||
assert.strictEqual(util.isPrimitive(function() {}), false);
|
||||
assert.strictEqual(util.isPrimitive(new Number(1)), false);
|
||||
assert.strictEqual(util.isPrimitive(new String('bla')), false);
|
||||
assert.strictEqual(util.isPrimitive(new Boolean(true)), false);
|
||||
assert.strictEqual(util.isPrimitive(1), true);
|
||||
assert.strictEqual(util.isPrimitive('bla'), true);
|
||||
assert.strictEqual(util.isPrimitive(true), true);
|
||||
assert.strictEqual(util.isPrimitive(undefined), true);
|
||||
assert.strictEqual(util.isPrimitive(null), true);
|
||||
assert.strictEqual(util.isPrimitive(Infinity), true);
|
||||
assert.strictEqual(util.isPrimitive(NaN), true);
|
||||
assert.strictEqual(util.isPrimitive(Symbol('symbol')), true);
|
||||
|
||||
// isBuffer
|
||||
assert.strictEqual(util.isBuffer('foo'), false);
|
||||
assert.strictEqual(util.isBuffer(Buffer.from('foo')), true);
|
||||
|
||||
// _extend
|
||||
assert.deepStrictEqual(util._extend({ a: 1 }), { a: 1 });
|
||||
assert.deepStrictEqual(util._extend({ a: 1 }, []), { a: 1 });
|
||||
@@ -48,6 +109,43 @@ assert.deepStrictEqual(util._extend({ a: 1 }, false), { a: 1 });
|
||||
assert.deepStrictEqual(util._extend({ a: 1 }, { b: 2 }), { a: 1, b: 2 });
|
||||
assert.deepStrictEqual(util._extend({ a: 1, b: 2 }, { b: 3 }), { a: 1, b: 3 });
|
||||
|
||||
// deprecated
|
||||
assert.strictEqual(util.isBoolean(true), true);
|
||||
assert.strictEqual(util.isBoolean(false), true);
|
||||
assert.strictEqual(util.isBoolean('string'), false);
|
||||
|
||||
assert.strictEqual(util.isNull(null), true);
|
||||
assert.strictEqual(util.isNull(undefined), false);
|
||||
assert.strictEqual(util.isNull(), false);
|
||||
assert.strictEqual(util.isNull('string'), false);
|
||||
|
||||
assert.strictEqual(util.isUndefined(undefined), true);
|
||||
assert.strictEqual(util.isUndefined(), true);
|
||||
assert.strictEqual(util.isUndefined(null), false);
|
||||
assert.strictEqual(util.isUndefined('string'), false);
|
||||
|
||||
assert.strictEqual(util.isNullOrUndefined(null), true);
|
||||
assert.strictEqual(util.isNullOrUndefined(undefined), true);
|
||||
assert.strictEqual(util.isNullOrUndefined(), true);
|
||||
assert.strictEqual(util.isNullOrUndefined('string'), false);
|
||||
|
||||
assert.strictEqual(util.isNumber(42), true);
|
||||
assert.strictEqual(util.isNumber(), false);
|
||||
assert.strictEqual(util.isNumber('string'), false);
|
||||
|
||||
assert.strictEqual(util.isString('string'), true);
|
||||
assert.strictEqual(util.isString(), false);
|
||||
assert.strictEqual(util.isString(42), false);
|
||||
|
||||
assert.strictEqual(util.isSymbol(Symbol()), true);
|
||||
assert.strictEqual(util.isSymbol(), false);
|
||||
assert.strictEqual(util.isSymbol('string'), false);
|
||||
|
||||
assert.strictEqual(util.isFunction(() => {}), true);
|
||||
assert.strictEqual(util.isFunction(function() {}), true);
|
||||
assert.strictEqual(util.isFunction(), false);
|
||||
assert.strictEqual(util.isFunction('string'), false);
|
||||
|
||||
assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');
|
||||
|
||||
{
|
||||
@@ -73,11 +171,6 @@ assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');
|
||||
util.types.isNativeError({ __proto__: Error.prototype }),
|
||||
false
|
||||
);
|
||||
// skipped because errors is from internal
|
||||
// assert.strictEqual(
|
||||
// util.types.isNativeError(new errors.codes.ERR_IPC_CHANNEL_CLOSED()),
|
||||
// true
|
||||
// );
|
||||
}
|
||||
|
||||
assert.throws(() => {
|
||||
|
||||
@@ -25,6 +25,7 @@ import fs from "node:fs";
|
||||
// import vm from 'node:vm';
|
||||
import assert from "assert";
|
||||
import { promisify } from "util";
|
||||
import { inspect } from "bun";
|
||||
|
||||
const stat = promisify(fs.stat);
|
||||
|
||||
@@ -294,7 +295,7 @@ describe("util.promisify", () => {
|
||||
[undefined, null, true, 0, "str", {}, [], Symbol()].forEach(input => {
|
||||
expect(() => {
|
||||
promisify(input);
|
||||
}).toThrow('The "original" argument must be of type Function');
|
||||
}).toThrow(`The "original" argument must be of type function.${invalidArgTypeHelper(input)}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -375,8 +375,6 @@ describe("util", () => {
|
||||
code: "ERR_INVALID_ARG_VALUE",
|
||||
},
|
||||
);
|
||||
|
||||
assert.strictEqual(util.styleText("red", "test"), "\u001b[31mtest\u001b[39m");
|
||||
});
|
||||
|
||||
describe("getSystemErrorName", () => {
|
||||
|
||||
Reference in New Issue
Block a user