mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
fix fs-open.test.js (#14311)
This commit is contained in:
@@ -23,6 +23,7 @@ const Shimmer = @import("../bindings/shimmer.zig").Shimmer;
|
||||
const Syscall = bun.sys;
|
||||
const URL = @import("../../url.zig").URL;
|
||||
const Value = std.json.Value;
|
||||
const validators = @import("./util/validators.zig");
|
||||
|
||||
pub const Path = @import("./path.zig");
|
||||
|
||||
@@ -1210,14 +1211,16 @@ pub fn timeLikeFromJS(globalObject: *JSC.JSGlobalObject, value: JSC.JSValue, _:
|
||||
|
||||
pub fn modeFromJS(ctx: JSC.C.JSContextRef, value: JSC.JSValue, exception: JSC.C.ExceptionRef) ?Mode {
|
||||
const mode_int = if (value.isNumber()) brk: {
|
||||
if (!value.isUInt32AsAnyInt()) {
|
||||
exception.* = ctx.ERR_OUT_OF_RANGE("The value of \"mode\" is out of range. It must be an integer. Received {d}", .{value.asNumber()}).toJS().asObjectRef();
|
||||
return null;
|
||||
}
|
||||
break :brk @as(Mode, @truncate(value.to(Mode)));
|
||||
const m = validators.validateUint32(ctx, value, "mode", .{}, false) catch return null;
|
||||
break :brk @as(Mode, @as(u24, @truncate(m)));
|
||||
} else brk: {
|
||||
if (value.isUndefinedOrNull()) return null;
|
||||
|
||||
if (!value.isString()) {
|
||||
_ = ctx.throwInvalidArgumentTypeValue("mode", "number", value);
|
||||
return null;
|
||||
}
|
||||
|
||||
// An easier method of constructing the mode is to use a sequence of
|
||||
// three octal digits (e.g. 765). The left-most digit (7 in the example),
|
||||
// specifies the permissions for the file owner. The middle digit (6 in
|
||||
@@ -1232,16 +1235,12 @@ pub fn modeFromJS(ctx: JSC.C.JSContextRef, value: JSC.JSValue, exception: JSC.C.
|
||||
}
|
||||
|
||||
break :brk std.fmt.parseInt(Mode, slice, 8) catch {
|
||||
JSC.throwInvalidArguments("Invalid mode string: must be an octal number", .{}, ctx, exception);
|
||||
var formatter = bun.JSC.ConsoleObject.Formatter{ .globalThis = ctx };
|
||||
exception.* = ctx.ERR_INVALID_ARG_VALUE("The argument 'mode' must be a 32-bit unsigned integer or an octal string. Received {}", .{value.toFmt(&formatter)}).toJS().asObjectRef();
|
||||
return null;
|
||||
};
|
||||
};
|
||||
|
||||
if (mode_int < 0) {
|
||||
JSC.throwInvalidArguments("Invalid mode: must be greater than or equal to 0.", .{}, ctx, exception);
|
||||
return null;
|
||||
}
|
||||
|
||||
return mode_int & 0o777;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,15 +97,17 @@ pub fn validateUint32(globalThis: *JSGlobalObject, value: JSValue, comptime name
|
||||
try throwErrInvalidArgType(globalThis, name_fmt, name_args, "number", value);
|
||||
}
|
||||
if (!value.isAnyInt()) {
|
||||
try throwRangeError(globalThis, "The value of \"" ++ name_fmt ++ "\" is out of range. It must be an integer. Received {s}", name_args ++ .{value});
|
||||
var formatter = JSC.ConsoleObject.Formatter{ .globalThis = globalThis };
|
||||
try throwRangeError(globalThis, "The value of \"" ++ name_fmt ++ "\" is out of range. It must be an integer. Received {}", name_args ++ .{value.toFmt(&formatter)});
|
||||
}
|
||||
const num: i64 = value.asInt52();
|
||||
const min: i64 = if (greater_than_zero) 1 else 0;
|
||||
const max: i64 = @intCast(std.math.maxInt(u32));
|
||||
if (num < min or num > max) {
|
||||
try throwRangeError(globalThis, "The value of \"" ++ name_fmt ++ "\" is out of range. It must be >= {d} and <= {d}. Received {s}", name_args ++ .{ min, max, value });
|
||||
var formatter = JSC.ConsoleObject.Formatter{ .globalThis = globalThis };
|
||||
try throwRangeError(globalThis, "The value of \"" ++ name_fmt ++ "\" is out of range. It must be >= {d} and <= {d}. Received {}", name_args ++ .{ min, max, value.toFmt(&formatter) });
|
||||
}
|
||||
return @truncate(num);
|
||||
return @truncate(@as(u63, @intCast(num)));
|
||||
}
|
||||
|
||||
pub fn validateString(globalThis: *JSGlobalObject, value: JSValue, comptime name_fmt: string, name_args: anytype) !void {
|
||||
|
||||
102
test/js/node/test/parallel/fs-open.test.js
Normal file
102
test/js/node/test/parallel/fs-open.test.js
Normal file
@@ -0,0 +1,102 @@
|
||||
//#FILE: test-fs-open.js
|
||||
//#SHA1: 0466ad8882a3256fdd8da5fc8da3167f6dde4fd6
|
||||
//-----------------
|
||||
'use strict';
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
test('fs.openSync throws ENOENT for non-existent file', () => {
|
||||
expect(() => {
|
||||
fs.openSync('/8hvftyuncxrt/path/to/file/that/does/not/exist', 'r');
|
||||
}).toThrow(expect.objectContaining({
|
||||
code: 'ENOENT',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
|
||||
test('fs.openSync succeeds for existing file', () => {
|
||||
expect(() => fs.openSync(__filename)).not.toThrow();
|
||||
});
|
||||
|
||||
test('fs.open succeeds with various valid arguments', async () => {
|
||||
await expect(fs.promises.open(__filename)).resolves.toBeDefined();
|
||||
await expect(fs.promises.open(__filename, 'r')).resolves.toBeDefined();
|
||||
await expect(fs.promises.open(__filename, 'rs')).resolves.toBeDefined();
|
||||
await expect(fs.promises.open(__filename, 'r', 0)).resolves.toBeDefined();
|
||||
await expect(fs.promises.open(__filename, 'r', null)).resolves.toBeDefined();
|
||||
});
|
||||
|
||||
test('fs.open throws for invalid mode argument', () => {
|
||||
expect(() => fs.open(__filename, 'r', 'boom', () => {})).toThrow(({
|
||||
code: 'ERR_INVALID_ARG_VALUE',
|
||||
name: 'TypeError',
|
||||
message: `The argument 'mode' must be a 32-bit unsigned integer or an octal string. Received boom`
|
||||
}));
|
||||
expect(() => fs.open(__filename, 'r', 5.5, () => {})).toThrow(({
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
name: 'RangeError',
|
||||
message: `The value of "mode" is out of range. It must be an integer. Received 5.5`
|
||||
}));
|
||||
expect(() => fs.open(__filename, 'r', -7, () => {})).toThrow(({
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
name: 'RangeError',
|
||||
message: `The value of "mode" is out of range. It must be >= 0 and <= 4294967295. Received -7`
|
||||
}));
|
||||
expect(() => fs.open(__filename, 'r', 4304967295, () => {})).toThrow(({
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
name: 'RangeError',
|
||||
message: `The value of "mode" is out of range. It must be >= 0 and <= 4294967295. Received 4304967295`
|
||||
}));
|
||||
});
|
||||
|
||||
test('fs.open throws for invalid argument combinations', () => {
|
||||
const invalidArgs = [[], ['r'], ['r', 0], ['r', 0, 'bad callback']];
|
||||
invalidArgs.forEach(args => {
|
||||
expect(() => fs.open(__filename, ...args)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
test('fs functions throw for invalid path types', () => {
|
||||
const invalidPaths = [false, 1, [], {}, null, undefined];
|
||||
invalidPaths.forEach(path => {
|
||||
expect(() => fs.open(path, 'r', () => {})).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
expect(() => fs.openSync(path, 'r')).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
expect(fs.promises.open(path, 'r')).rejects.toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
name: 'TypeError',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
test('fs functions throw for invalid modes', () => {
|
||||
const invalidModes = [false, [], {}];
|
||||
invalidModes.forEach(mode => {
|
||||
expect(() => fs.open(__filename, 'r', mode, () => {})).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
expect(() => fs.openSync(__filename, 'r', mode)).toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
expect(fs.promises.open(__filename, 'r', mode)).rejects.toThrow(expect.objectContaining({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
message: expect.any(String)
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
//<#END_FILE: test-fs-open.js
|
||||
Reference in New Issue
Block a user