/*--- includes: [compatFs.js, compatBuffer.js, runTsuite.js] flags: [async] ---*/ let unique = 0; function p(args, default_opts) { let params = Object.assign({}, default_opts, args); if (params.args) { let fname = params.args[0]; if (fname[0] == '@') { let gen = `${test_dir}/fs_test_${unique++}`; params.args = params.args.map(v => v); params.args[0] = gen + fname.slice(1); } } return params; } function has_quickjs() { return (typeof njs != 'undefined' && njs.engine == 'QuickJS'); } function promisify(f) { return function (...args) { return new Promise((resolve, reject) => { function callback(err, result) { if (err) { return reject(err); } else { resolve(result); } } args.push(callback); f.apply(this, args); }); }; } async function method(name, params) { let data = null; switch (params.type) { case "sync": data = fs[name + "Sync"].apply(null, params.args); break; case "callback": data = await promisify(fs[name]).apply(null, params.args); break; case "promise": data = await fs.promises[name].apply(null, params.args); break; } return data; } async function readfile_test(params) { let data = await method("readFile", params).catch(e => ({error:e})); if (params.slice && !data.error) { data = data.slice.apply(data, params.slice); } if (params.check) { if (!params.check(data, params)) { throw Error(`readFile failed check`); } } else if (params.exception) { throw data.error; } else { let success = true; if (data instanceof Buffer) { if (data.compare(params.expected) != 0) { success = false; } } else if (data != params.expected) { success = false; } if (!success) { throw Error(`readFile unexpected data`); } } return 'SUCCESS'; } let readfile_tests = () => [ { args: ["test/fs/utf8"], expected: Buffer.from("αβZγ") }, { args: [Buffer.from("@test/fs/utf8").slice(1)], expected: Buffer.from("αβZγ") }, { args: ["test/fs/utf8", "utf8"], expected: "αβZγ" }, { args: ["test/fs/utf8", {encoding: "utf8", flags:"r+"}], expected: "αβZγ" }, { args: ["test/fs/nonexistent"], check: (err, params) => { let e = err.error; if (e.syscall != 'open') { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "ENOENT") { throw Error(`${e.code} unexpected code`); } if (e.path != "test/fs/nonexistent") { throw Error(`${e.path} unexpected path`); } return true; } }, { args: ["test/fs/non_utf8", "utf8"], expected: "��", skip: () => has_quickjs() }, { args: ["test/fs/non_utf8", {encoding: "hex"}], expected: "8080" }, { args: ["test/fs/non_utf8", "base64"], expected: "gIA=" }, { args: ["test/fs/ascii", "utf8"], expected: "x".repeat(600) }, { args: ["test/fs/ascii", { encoding:"utf8", flags: "r+"}], expected: "x".repeat(600) }, { args: [Buffer.from([0x80, 0x80])], exception: "Error: No such file or directory" }, { args: ['x'.repeat(8192)], exception: "TypeError: \"path\" is too long" }, { args: ["/proc/version"], slice:[0,5], expected: Buffer.from("Linux"), check: (data, params) => { if (data.error) { let e = data.error; if (e.syscall != 'open') { throw Error(`${e.syscall} unexpected syscall`); } return true; } return data.compare(params.expected) == 0; } }, { args: ["/proc/cpuinfo"], check: (data, params) => { if (data.error) { let e = data.error; if (e.syscall != 'open') { throw Error(`${e.syscall} unexpected syscall`); } return true; } return /processor/.test(data); } }, ]; let readFile_tsuite = { name: "fs readFile", skip: () => (!has_buffer()), T: readfile_test, prepare_args: p, opts: { type: "callback" }, get tests() { return readfile_tests() }, }; let readFileSync_tsuite = { name: "fs readFileSync", skip: () => (!has_buffer()), T: readfile_test, prepare_args: p, opts: { type: "sync" }, get tests() { return readfile_tests() }, }; let readFileP_tsuite = { name: "fsp readFile", skip: () => (!has_buffer()), T: readfile_test, prepare_args: p, opts: { type: "promise" }, get tests() { return readfile_tests() }, }; async function writefile_test(params) { let fname = params.args[0]; try { fs.unlinkSync(fname); } catch (e) {} let data = await method("writeFile", params).catch(e => ({error:e})); if (!data) { data = fs.readFileSync(fname); } try { fs.unlinkSync(fname); } catch (e) {} if (params.check) { if (!params.check(data, params)) { throw Error(`writeFile failed check`); } } else if (params.exception) { throw data.error; } else { if (data.compare(params.expected) != 0) { throw Error(`writeFile unexpected data`); } } return 'SUCCESS'; } let writefile_tests = () => [ { args: ["@", Buffer.from(Buffer.alloc(4).fill(65).buffer, 1)], expected: Buffer.from("AAA") }, { args: ["@", Buffer.from("XYZ"), "utf8"], expected: Buffer.from("XYZ") }, { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}], expected: Buffer.from("XYZ") }, { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)], expected: Buffer.from("BBB"), skip: () => has_quickjs() }, { args: ["@", new Uint8Array(Buffer.from("ABCD"))], expected: Buffer.from("ABCD")}, { args: ["@", "XYZ"], expected: Buffer.from("XYZ")}, { args: ["@", "78797a", "hex"], expected: Buffer.from("xyz") }, { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyz") }, { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyz"), optional: true }, { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"}, { args: ["/invalid_path", "XYZ"], check: (err, params) => { let e = err.error; if (e.syscall != 'open') { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "EACCES" && e.code != "EROFS") { throw Error(`${e.code} unexpected code`); } return true; } }, ]; let writeFile_tsuite = { name: "fs writeFile", skip: () => (!has_buffer()), T: writefile_test, prepare_args: p, opts: { type: "callback" }, get tests() { return writefile_tests() }, }; let writeFileSync_tsuite = { name: "fs writeFileSync", skip: () => (!has_buffer()), T: writefile_test, prepare_args: p, opts: { type: "sync" }, get tests() { return writefile_tests() }, }; let writeFileP_tsuite = { name: "fsp writeFile", skip: () => (!has_buffer()), T: writefile_test, prepare_args: p, opts: { type: "promise" }, get tests() { return writefile_tests() }, }; async function append_test(params) { let fname = params.args[0]; try { fs.unlinkSync(fname); } catch (e) {} let data = await method("appendFile", params).catch(e => ({error:e})); data = await method("appendFile", params).catch(e => ({error:e})); if (!data) { data = fs.readFileSync(fname); } try { fs.unlinkSync(fname); } catch (e) {} if (params.check) { if (!params.check(data, params)) { throw Error(`appendFile failed check`); } } else if (params.exception) { throw data.error; } else { if (data.compare(params.expected) != 0) { throw Error(`appendFile unexpected data`); } } return 'SUCCESS'; } let append_tests = () => [ { args: ["@", Buffer.from(Buffer.alloc(4).fill(65).buffer, 1)], expected: Buffer.from("AAAAAA") }, { args: ["@", Buffer.from("XYZ"), "utf8"], expected: Buffer.from("XYZXYZ") }, { args: ["@", Buffer.from("XYZ"), {encoding: "utf8", mode: 0o666}], expected: Buffer.from("XYZXYZ") }, { args: ["@", new DataView(Buffer.alloc(3).fill(66).buffer)], expected: Buffer.from("BBBBBB"), skip: () => has_quickjs() }, { args: ["@", new Uint8Array(Buffer.from("ABCD"))], expected: Buffer.from("ABCDABCD")}, { args: ["@", "XYZ"], expected: Buffer.from("XYZXYZ")}, { args: ["@", "78797a", "hex"], expected: Buffer.from("xyzxyz") }, { args: ["@", "eHl6", "base64"], expected: Buffer.from("xyzxyz") }, { args: ["@", "eHl6", {encoding: "base64url"}], expected: Buffer.from("xyzxyz"), optional: true }, { args: ["@", Symbol("XYZ")], exception: "TypeError: Cannot convert a Symbol value to a string"}, { args: ["/invalid_path", "XYZ"], check: (err, params) => { let e = err.error; if (e.syscall != 'open') { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "EACCES" && e.code != "EROFS") { throw Error(`${e.code} unexpected code`); } return true; } }, ]; let appendFile_tsuite = { name: "fs appendFile", skip: () => (!has_buffer()), T: append_test, prepare_args: p, opts: { type: "callback" }, get tests() { return append_tests() }, }; let appendFileSync_tsuite = { name: "fs appendFileSync", skip: () => (!has_buffer()), T: append_test, prepare_args: p, opts: { type: "sync" }, get tests() { return append_tests() }, }; let appendFileP_tsuite = { name: "fsp appendFile", skip: () => (!has_buffer()), T: append_test, prepare_args: p, opts: { type: "promise" }, get tests() { return append_tests() }, }; async function exists_test(params) { let res = await method("exists", params); if (res !== params.expected) { throw Error(`exists failed check`); } return 'SUCCESS'; } let exists_tests = () => [ { args: ["test/fs/ascii"], expected: true }, { args: ["test/fs"], expected: true }, { args: ["test/fs_NONEXISTENT/ascii"], expected: false }, { args: ["test/fs/ascii_NONEXISTENT"], expected: false }, ]; let existsSync_tsuite = { name: "fs existsSync", skip: () => (!has_buffer()), T: exists_test, prepare_args: p, opts: { type: "sync" }, get tests() { return exists_tests() }, }; async function realpath_test(params) { let data = await method("realpath", params); if (!params.check(data)) { throw Error(`realpath failed check`); } return 'SUCCESS'; } let realpath_tests = () => [ { args: ["test/fs/.."], check: (data) => data.endsWith("test") }, { args: ["test/fs/ascii", {encoding:'buffer'}], check: (data) => data instanceof Buffer }, ]; let realpath_tsuite = { name: "fs realpath", skip: () => (!has_buffer()), T: realpath_test, prepare_args: p, opts: { type: "callback" }, get tests() { return realpath_tests() }, }; let realpathSync_tsuite = { name: "fs realpathSync", skip: () => (!has_buffer()), T: realpath_test, prepare_args: p, opts: { type: "sync" }, get tests() { return realpath_tests() }, }; let realpathP_tsuite = { name: "fsp realpath", skip: () => (!has_buffer()), T: realpath_test, prepare_args: p, opts: { type: "promise" }, get tests() { return realpath_tests() }, }; async function readlink_test(params) { let lname = params.args[0]; try { fs.unlinkSync(lname); } catch (e) {} fs.symlinkSync("test/fs/ascii", lname); let data = await method("readlink", params); if (!params.check(data)) { throw Error(`readlink failed check`); } return 'SUCCESS'; } let readlink_tests = () => [ { args: [`${test_dir}/symlink`], check: (data) => data.endsWith("test/fs/ascii") }, { args: [`${test_dir}/symlink`, {encoding:'buffer'}], check: (data) => data instanceof Buffer }, { args: [`${test_dir}/symlink`, {encoding:'hex'}], check: (data) => data.endsWith("746573742f66732f6173636969") }, ]; let readlink_tsuite = { name: "fs readlink", skip: () => (!has_buffer()), T: readlink_test, prepare_args: p, opts: { type: "callback" }, get tests() { return readlink_tests() }, }; let readlinkSync_tsuite = { name: "fs readlinkSync", skip: () => (!has_buffer()), T: readlink_test, prepare_args: p, opts: { type: "sync" }, get tests() { return readlink_tests() }, }; let readlinkP_tsuite = { name: "fsp readlink", skip: () => (!has_buffer()), T: readlink_test, prepare_args: p, opts: { type: "promise" }, get tests() { return readlink_tests() }, }; async function method_test(params) { if (params.init) { params.init(params); } let ret = await method(params.method, params).catch(e => ({error:e})); if (params.check && !params.check(ret, params)) { throw Error(`${params.method} failed check`); } return 'SUCCESS'; } function contains(arr, elts) { return elts.every(el => { let r = arr.some(v => el == v); if (!r) { throw Error(`${el} is not found`); } return r; }); } let stat_tests = () => [ { args: ["/invalid_path"], check: (err, params) => { let e = err.error; if (e.syscall != params.method) { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "ENOENT") { throw Error(`${e.code} unexpected code`); } return true; } }, { args: ["@_link"], init: (params) => { let lname = params.args[0]; let fname = lname.slice(0, -5); /* making symbolic link. */ try { fs.unlinkSync(fname); } catch (e) {} try { fs.unlinkSync(lname); } catch (e) {} fs.writeFileSync(fname, fname); fname = fs.realpathSync(fname); fs.symlinkSync(fname, lname); }, check: (st, params) => { switch (params.method) { case "stat": if (!st.isFile()) { throw Error(`${params.args[0]} is not a file`); } break; case "lstat": if (!st.isSymbolicLink()) { throw Error(`${params.args[0]} is not a link`); } break; } return true; } }, { args: ["test/fs/ascii"], check: (st) => contains(Object.keys(st), [ "atime", "atimeMs", "birthtime", "birthtimeMs", "blksize", "blocks", "ctime", "ctimeMs", "dev", "gid", "ino", "mode", "mtime", "mtimeMs","nlink", "rdev", "size", "uid" ]) }, { args: ["test/fs/ascii"], check: (st) => Object.keys(st).every(p => { let v = st[p]; if (p == 'atime' || p == 'ctime' || p == 'mtime' || p == 'birthtime') { if (!(v instanceof Date)) { throw Error(`${p} is not an instance of Date`); } return true; } if ((typeof v) != 'number') { throw Error(`${p} is not an instance of Number`); } return true; }) }, { args: ["test/fs/ascii"], check: (st) => ['atime', 'birthtime', 'ctime', 'mtime'].every(p => { let date = st[p].valueOf(); let num = st[p + 'Ms']; if (Math.abs(date - num) > 1) { throw Error(`${p}:${date} != ${p+'Ms'}:${num}`); } return true; }) }, { args: [test_dir], check: (st) => ['isBlockDevice', 'isCharacterDevice', 'isDirectory', 'isFIFO', 'isFile', 'isSocket', 'isSymbolicLink'].every(m => { let r = st[m](); if (!(r == (m == 'isDirectory'))) { throw Error(`${m} is ${r}`); } return true; }) }, ]; let stat_tsuite = { name: "fs stat", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "callback", method: "stat" }, get tests() { return stat_tests() }, }; let statSync_tsuite = { name: "fs statSync", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "sync", method: "stat" }, get tests() { return stat_tests() }, }; let statP_tsuite = { name: "fsp stat", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "promise", method: "stat" }, get tests() { return stat_tests() }, }; let lstat_tsuite = { name: "fs lstat", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "callback", method: "lstat" }, get tests() { return stat_tests() }, }; let lstatSync_tsuite = { name: "fs lstatSync", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "sync", method: "lstat" }, get tests() { return stat_tests() }, }; let lstatP_tsuite = { name: "fsp lstat", skip: () => (!has_fs_symbolic_link() || !has_buffer()), T: method_test, prepare_args: p, opts: { type: "promise", method: "lstat" }, get tests() { return stat_tests() }, }; let open_check = (fh, params) => { if (params.type == 'promise') { try { if (typeof fh.fd != 'number') { throw Error(`filehandle.fd:${fh.fd} is not an instance of Number`); } ['read', 'write', 'close', 'valueof'].every(v => { if (typeof fh[v] != 'function') { throw Error(`filehandle.close:${fh[v]} is not an instance of function`); } }); let mode = fs.fstatSync(fh.fd).mode & 0o777; if (params.mode && params.mode != mode) { throw Error(`opened mode ${mode} != ${params.mode}`); } } finally { fh.close(); } } else { try { if (typeof fh != 'number') { throw Error(`fd:${fh} is not an instance of Number`); } let mode = fs.fstatSync(fh).mode & 0o777; if (params.mode && params.mode != mode) { throw Error(`opened mode ${mode} != ${params.mode}`); } } finally { fs.closeSync(fh); } } return true; }; let open_tests = () => [ { args: ["test/fs/ascii"], check: open_check, }, { args: ["@", 'w', 0o600], mode: 0o600, check: open_check, }, { args: ["@", 'a', 0o700], mode: 0o700, check: open_check, }, { args: ["@", 'r'], check: (err, params) => { let e = err.error; if (e.syscall != params.method) { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "ENOENT") { throw Error(`${e.code} unexpected code`); } return true; }, }, { args: ["/invalid_path"], check: (err, params) => { let e = err.error; if (e.syscall != params.method) { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "ENOENT") { throw Error(`${e.code} unexpected code`); } return true; }, }, ]; let openSync_tsuite = { name: "fs openSync", skip: () => (!has_buffer()), T: method_test, prepare_args: p, opts: { type: "sync", method: "open" }, get tests() { return open_tests() }, }; let openP_tsuite = { name: "fsp open", skip: () => (!has_buffer()), T: method_test, prepare_args: p, opts: { type: "promise", method: "open" }, get tests() { return open_tests() }, }; let close_tests = () => [ { args: [ fs.openSync("test/fs/ascii") ], check: (undef, params) => undef === undefined, }, { args: [ (() => { let fd = fs.openSync("test/fs/ascii"); fs.closeSync(fd); return fd})() ], check: (err, params) => { let e = err.error; if (e.syscall != params.method) { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "EBADF") { throw Error(`${e.code} unexpected code`); } return true; }, }, ]; let closeSync_tsuite = { name: "fs closeSync", skip: () => (!has_buffer()), T: method_test, prepare_args: p, opts: { type: "sync", method: "close" }, get tests() { return close_tests() }, }; function read_test(params) { let fd, err; let fn = `${test_dir}/fs_read_test_${Math.round(Math.random() * 1000000)}`; let out = []; fs.writeFileSync(fn, params.content); try { fd = fs.openSync(fn); let buffer = Buffer.alloc(4); buffer.fill('#'); for (var i = 0; i < params.read.length; i++) { let args = params.read[i].map(v => v); args.unshift(buffer); args.unshift(fd); let bytesRead = fs.readSync.apply(null, args); out.push([bytesRead, Buffer.from(buffer)]); } } catch (e) { if (!e.syscall && !params.check) { throw e; } err = e; } finally { fs.closeSync(fd); } if (!err && params.expected) { let expected = params.expected; if (out.length != expected.length) { throw Error(`unexpected readSync number of outputs ${out.length} != ${expected.length}`); } for (var i = 0; i < expected.length; i++) { if (expected[i][0] != out[i][0]) { throw Error(`unexpected readSync bytesRead:${out[i][0]} != ${expected[i][0]}`); } if (expected[i][1].compare(out[i][1]) != 0) { throw Error(`unexpected readSync buffer:${out[i][1]} != ${expected[i][1]}`); } } } if (params.check && !params.check(err, params)) { throw Error(`${params.method} failed check`); } return 'SUCCESS'; } async function readFh_test(params) { let fh, err; let fn = `${test_dir}/fs_read_test_${Math.round(Math.random() * 1000000)}`; let out = []; fs.writeFileSync(fn, params.content); try { fh = await fs.promises.open(fn); let buffer = Buffer.alloc(4); buffer.fill('#'); for (var i = 0; i < params.read.length; i++) { let args = params.read[i].map(v => v); args.unshift(buffer); let bs = await fh.read.apply(fh, args); out.push([bs.bytesRead, Buffer.from(bs.buffer)]); } } catch (e) { if (!e.syscall && !params.check) { throw e; } err = e; } finally { await fh.close(); } if (!err && params.expected) { let expected = params.expected; if (out.length != expected.length) { throw Error(`unexpected read number of outputs ${out.length} != ${expected.length}`); } for (var i = 0; i < expected.length; i++) { if (expected[i][0] != out[i][0]) { throw Error(`unexpected read bytesRead:${out[i][0]} != ${expected[i][0]}`); } if (expected[i][1].compare(out[i][1]) != 0) { throw Error(`unexpected read buffer:${out[i][1]} != ${expected[i][1]}`); } } } if (params.check && !params.check(err, params)) { throw Error(`${params.method} failed check`); } return 'SUCCESS'; } let read_tests = () => [ { content: "ABC", read: [ [0, 3], ], expected: [ [3, Buffer.from("ABC#")], ], }, { content: "ABC", read: [ [1, 2], ], expected: [ [2, Buffer.from("#AB#")], ], }, { content: "ABC", read: [ [1, 2, 1], ], expected: [ [2, Buffer.from("#BC#")], ], }, { content: "__ABCDE", read: [ [0, 4], [0, 4], [2, 2, 0], [0, 4, null], ], expected: [ [4, Buffer.from("__AB")], [3, Buffer.from("CDEB")], [2, Buffer.from("CD__")], [0, Buffer.from("CD__")], ], }, { content: "ABC", read: [ [0, 5], ], check: (err, params) => { if (!(err instanceof RangeError)) { throw Error(`${err.message} unexpected exception`); } return true; }, }, { content: "ABC", read: [ [2, 3], ], check: (err, params) => { if (!(err instanceof RangeError)) { throw Error(`${err.message} unexpected exception`); } return true; }, }, ]; let readSync_tsuite = { name: "fs readSync", skip: () => (!has_buffer()), T: read_test, prepare_args: p, get tests() { return read_tests() }, }; let readFh_tsuite = { name: "fh read", skip: () => (!has_buffer()), T: readFh_test, prepare_args: p, get tests() { return read_tests() }, }; function write_test(params) { let fd, err; try { fd = fs.openSync.apply(null, params.args); for (var i = 0; i < params.write.length; i++) { let args = params.write[i].map(v => v); args.unshift(fd); let bytesWritten = fs.writeSync.apply(null, args); if (params.written && bytesWritten != params.written) { throw Error(`bw.bytesWritten unexpected value:${bw.bytesWritten}`); } } } catch (e) { if (!e.syscall && !params.check) { throw e; } err = e; } finally { fs.closeSync(fd); } if (!err && params.expected) { let data = fs.readFileSync(params.args[0]); if (data.compare(params.expected) != 0) { throw Error(`fh.write unexpected data:${data}`); } } if (params.check && !params.check(err, params)) { throw Error(`${params.method} failed check`); } return 'SUCCESS'; } async function writeFh_test(params) { let fh, err; try { fh = await fs.promises.open.apply(null, params.args); for (var i = 0; i < params.write.length; i++) { let bw = await fh.write.apply(fh, params.write[i]); if (params.written && bw.bytesWritten != params.written) { throw Error(`bw.bytesWritten unexpected value:${bw.bytesWritten}`); } if (params.buffer && (typeof params.buffer == 'string' && params.buffer != bw.buffer || typeof params.buffer == 'object' && params.buffer.compare(bw.buffer) != 0)) { throw Error(`bw.buffer unexpected value:${bw.buffer}`); } } } catch (e) { if (!e.syscall && !params.check) { throw e; } err = e; } finally { await fh.close(); } if (!err && params.expected) { let data = fs.readFileSync(params.args[0]); if (data.compare(params.expected) != 0) { throw Error(`fh.write unexpected data:${data}`); } } if (params.check && !params.check(err, params)) { throw Error(`${params.method} failed check`); } return 'SUCCESS'; } let write_tests = () => [ { args: ["@", 'w'], write: [ ["ABC", undefined], ["DE", null], ["F"], ], expected: Buffer.from("ABCDEF"), }, { args: ["@", 'w'], write: [ ["XXXXXX"], ["YYYY", 1], ["ZZ", 2], ], expected: Buffer.from("XYZZYX"), }, { args: ["@", 'w'], write: [ ["ABC", null, 'utf8'] ], written: 3, buffer: 'ABC', expected: Buffer.from("ABC"), }, { args: ["test/fs/ascii"], write: [ ["ABC"] ], check: (err, params) => { let e = err; if (e.syscall != 'write') { throw Error(`${e.syscall} unexpected syscall`); } if (e.code != "EBADF") { throw Error(`${e.code} unexpected code`); } return true; }, }, { args: ["@", 'w'], write: [ [Buffer.from("ABC"), 0, 3], [Buffer.from("DE"), 0, 2, null], [Buffer.from("F"), 0, 1], ], expected: Buffer.from("ABCDEF"), }, { args: ["@", 'w'], write: [ [Buffer.from("__XXXXXX"), 2], [Buffer.from("__YYYY__"), 2, 4, 1], [Buffer.from("ZZ"), 0, 2, 2], ], expected: Buffer.from("XYZZYX"), }, { args: ["@", 'w'], write: [ [Buffer.from("__ABC__"), 2, 3] ], written: 3, buffer: Buffer.from('__ABC__'), expected: Buffer.from("ABC"), }, { args: ["@", 'w'], write: [ [Buffer.from("__ABC__"), 7] ], written: 0, }, { args: ["@", 'w'], write: [ [Buffer.from("__ABC__"), 8] ], check: (err, params) => { if (!(err instanceof RangeError)) { throw Error(`${err.message} unexpected exception`); } return true; }, }, { args: ["@", 'w'], write: [ [Buffer.from("__ABC__"), 7, 1] ], check: (err, params) => { if (!(err instanceof RangeError)) { throw Error(`${err.message} unexpected exception`); } return true; }, }, ]; let writeSync_tsuite = { name: "fs writeSync", skip: () => (!has_buffer()), T: write_test, prepare_args: p, get tests() { return write_tests() }, }; let writeFh_tsuite = { name: "fh write", skip: () => (!has_buffer()), T: writeFh_test, prepare_args: p, get tests() { return write_tests() }, }; run([ readFile_tsuite, readFileSync_tsuite, readFileP_tsuite, writeFile_tsuite, writeFileSync_tsuite, writeFileP_tsuite, appendFile_tsuite, appendFileSync_tsuite, appendFileP_tsuite, existsSync_tsuite, realpath_tsuite, realpathSync_tsuite, realpathP_tsuite, readlink_tsuite, readlinkSync_tsuite, readlinkP_tsuite, stat_tsuite, statSync_tsuite, statP_tsuite, lstat_tsuite, lstatSync_tsuite, lstatP_tsuite, openSync_tsuite, openP_tsuite, readSync_tsuite, readFh_tsuite, writeSync_tsuite, writeFh_tsuite, closeSync_tsuite, ]) .then($DONE, $DONE);