From 9dbf173f75828ccd86b9fa9cc9575a76aff69555 Mon Sep 17 00:00:00 2001 From: Ryan Zimmerman Date: Mon, 31 Oct 2022 14:25:13 -0400 Subject: [PATCH] Add promise support for fs.readv (#970) --- lib/fs/__tests__/multi-param.test.js | 64 ++++++++++++++++++++++++++++ lib/fs/index.js | 18 +++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/lib/fs/__tests__/multi-param.test.js b/lib/fs/__tests__/multi-param.test.js index a22046bf..75ed7950 100644 --- a/lib/fs/__tests__/multi-param.test.js +++ b/lib/fs/__tests__/multi-param.test.js @@ -149,6 +149,70 @@ describe('fs.write()', () => { }) }) +describe('fs.readv()', () => { + let TEST_FILE + let TEST_DATA + let TEST_FD + + beforeEach(() => { + TEST_FILE = path.join(os.tmpdir(), 'fs-extra', 'readv-test-file') + TEST_DATA = crypto.randomBytes(SIZE) + fs.writeFileSync(TEST_FILE, TEST_DATA) + TEST_FD = fs.openSync(TEST_FILE, 'r') + }) + + afterEach(() => { + return fs.close(TEST_FD) + .then(() => fs.remove(TEST_FILE)) + }) + + describe('with promises', () => { + it('returns an object', () => { + const bufferArray = [Buffer.alloc(SIZE / 2), Buffer.alloc(SIZE / 2)] + return fs.readv(TEST_FD, bufferArray, 0) + .then(({ bytesRead, buffers }) => { + assert.strictEqual(bytesRead, SIZE, 'bytesRead is correct') + assert.deepStrictEqual(buffers, bufferArray, 'returned data matches mutated input param') + assert.deepStrictEqual(Buffer.concat(buffers), TEST_DATA, 'data is correct') + }) + }) + + it('returns an object when minimal arguments are passed', () => { + const bufferArray = [Buffer.alloc(SIZE / 2), Buffer.alloc(SIZE / 2)] + return fs.readv(TEST_FD, bufferArray) + .then(({ bytesRead, buffers }) => { + assert.strictEqual(bytesRead, SIZE, 'bytesRead is correct') + assert.deepStrictEqual(buffers, bufferArray, 'returned data matches mutated input param') + assert.deepStrictEqual(Buffer.concat(buffers), TEST_DATA, 'data is correct') + }) + }) + }) + + describe('with callbacks', () => { + it('works', done => { + const bufferArray = [Buffer.alloc(SIZE / 2), Buffer.alloc(SIZE / 2)] + fs.readv(TEST_FD, bufferArray, 0, (err, bytesRead, buffers) => { + assert.ifError(err) + assert.strictEqual(bytesRead, SIZE, 'bytesRead is correct') + assert.deepStrictEqual(buffers, bufferArray, 'returned data matches mutated input param') + assert.deepStrictEqual(Buffer.concat(buffers), TEST_DATA, 'data is correct') + done() + }) + }) + + it('works when minimal arguments are passed', done => { + const bufferArray = [Buffer.alloc(SIZE / 2), Buffer.alloc(SIZE / 2)] + fs.readv(TEST_FD, bufferArray, (err, bytesRead, buffers) => { + assert.ifError(err) + assert.strictEqual(bytesRead, SIZE, 'bytesRead is correct') + assert.deepStrictEqual(buffers, bufferArray, 'returned data matches mutated input param') + assert.deepStrictEqual(Buffer.concat(buffers), TEST_DATA, 'data is correct') + done() + }) + }) + }) +}) + describe('fs.writev()', () => { let TEST_FILE let TEST_DATA diff --git a/lib/fs/index.js b/lib/fs/index.js index 0bce0e8c..3c3ec511 100644 --- a/lib/fs/index.js +++ b/lib/fs/index.js @@ -65,7 +65,7 @@ exports.exists = function (filename, callback) { }) } -// fs.read(), fs.write(), & fs.writev() need special treatment due to multiple callback args +// fs.read(), fs.write(), fs.readv(), & fs.writev() need special treatment due to multiple callback args exports.read = function (fd, buffer, offset, length, position, callback) { if (typeof callback === 'function') { @@ -97,6 +97,22 @@ exports.write = function (fd, buffer, ...args) { }) } +// Function signature is +// s.readv(fd, buffers[, position], callback) +// We need to handle the optional arg, so we use ...args +exports.readv = function (fd, buffers, ...args) { + if (typeof args[args.length - 1] === 'function') { + return fs.readv(fd, buffers, ...args) + } + + return new Promise((resolve, reject) => { + fs.readv(fd, buffers, ...args, (err, bytesRead, buffers) => { + if (err) return reject(err) + resolve({ bytesRead, buffers }) + }) + }) +} + // Function signature is // s.writev(fd, buffers[, position], callback) // We need to handle the optional arg, so we use ...args