Skip to content

Commit

Permalink
Allow passing Buffer to the input option (#1029)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored May 7, 2024
1 parent 5182195 commit 40fdc75
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 47 deletions.
4 changes: 1 addition & 3 deletions lib/transform/encoding-transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ const encodingUint8ArrayGenerator = function * (textEncoder, chunk) {
};

const encodingStringGenerator = function * (stringDecoder, chunk) {
yield Buffer.isBuffer(chunk) || isUint8Array(chunk)
? stringDecoder.write(chunk)
: chunk;
yield isUint8Array(chunk) ? stringDecoder.write(chunk) : chunk;
};

const encodingStringFinal = function * (stringDecoder) {
Expand Down
3 changes: 1 addition & 2 deletions lib/transform/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ const validateStringTransformReturn = function * (optionName, chunk) {
validateEmptyReturn(optionName, chunk);

if (typeof chunk !== 'string' && !isUint8Array(chunk)) {
const typeName = Buffer.isBuffer(chunk) ? 'a buffer' : typeof chunk;
throw new TypeError(`The \`${optionName}\` option's function must yield a string or an Uint8Array, not ${typeName}.`);
throw new TypeError(`The \`${optionName}\` option's function must yield a string or an Uint8Array, not ${typeof chunk}.`);
}

yield chunk;
Expand Down
4 changes: 2 additions & 2 deletions lib/utils/uint-array.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Buffer} from 'node:buffer';
import {StringDecoder} from 'node:string_decoder';

const {toString: objectToString} = Object.prototype;

export const isArrayBuffer = value => objectToString.call(value) === '[object ArrayBuffer]';

export const isUint8Array = value => objectToString.call(value) === '[object Uint8Array]' && !Buffer.isBuffer(value);
// Is either Uint8Array or Buffer
export const isUint8Array = value => objectToString.call(value) === '[object Uint8Array]';

export const bufferToUint8Array = buffer => new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);

Expand Down
4 changes: 2 additions & 2 deletions test/io/input-option.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ const testInput = async (t, input, execaMethod) => {

test('input option can be a String', testInput, 'foobar', runExeca);
test('input option can be a Uint8Array', testInput, foobarUint8Array, runExeca);
test('input option can be a Buffer', testInput, foobarBuffer, runExeca);
test('input option can be a String - sync', testInput, 'foobar', runExecaSync);
test('input option can be a Uint8Array - sync', testInput, foobarUint8Array, runExecaSync);
test('input option can be a Buffer - sync', testInput, foobarBuffer, runExecaSync);
test('input option can be used with $', testInput, 'foobar', runScript);
test('input option can be used with $.sync', testInput, 'foobar', runScriptSync);

Expand All @@ -36,15 +38,13 @@ const testInvalidInput = async (t, input, execaMethod) => {
}, {message: /a string, a Uint8Array/});
};

test('input option cannot be a Buffer', testInvalidInput, foobarBuffer, execa);
test('input option cannot be an ArrayBuffer', testInvalidInput, foobarArrayBuffer, execa);
test('input option cannot be a DataView', testInvalidInput, foobarDataView, execa);
test('input option cannot be a Uint16Array', testInvalidInput, foobarUint16Array, execa);
test('input option cannot be 0', testInvalidInput, 0, execa);
test('input option cannot be false', testInvalidInput, false, execa);
test('input option cannot be null', testInvalidInput, null, execa);
test('input option cannot be a non-Readable stream', testInvalidInput, new Writable(), execa);
test('input option cannot be a Buffer - sync', testInvalidInput, foobarBuffer, execaSync);
test('input option cannot be an ArrayBuffer - sync', testInvalidInput, foobarArrayBuffer, execaSync);
test('input option cannot be a DataView - sync', testInvalidInput, foobarDataView, execaSync);
test('input option cannot be a Uint16Array - sync', testInvalidInput, foobarUint16Array, execaSync);
Expand Down
31 changes: 19 additions & 12 deletions test/stdio/typed-array.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,33 @@ import test from 'ava';
import {execa, execaSync} from '../../index.js';
import {setFixtureDirectory} from '../helpers/fixtures-directory.js';
import {getStdio} from '../helpers/stdio.js';
import {foobarUint8Array, foobarString} from '../helpers/input.js';
import {foobarUint8Array, foobarBuffer, foobarString} from '../helpers/input.js';

setFixtureDirectory();

const testUint8Array = async (t, fdNumber, execaMethod) => {
const {stdout} = await execaMethod('stdin-fd.js', [`${fdNumber}`], getStdio(fdNumber, foobarUint8Array));
const testUint8Array = async (t, fdNumber, stdioOption, execaMethod) => {
const {stdout} = await execaMethod('stdin-fd.js', [`${fdNumber}`], getStdio(fdNumber, stdioOption));
t.is(stdout, foobarString);
};

test('stdin option can be a Uint8Array', testUint8Array, 0, execa);
test('stdio[*] option can be a Uint8Array', testUint8Array, 3, execa);
test('stdin option can be a Uint8Array - sync', testUint8Array, 0, execaSync);
test('stdin option can be a Uint8Array', testUint8Array, 0, foobarUint8Array, execa);
test('stdio[*] option can be a Uint8Array', testUint8Array, 3, foobarUint8Array, execa);
test('stdin option can be a Uint8Array - sync', testUint8Array, 0, foobarUint8Array, execaSync);
test('stdin option can be a Buffer', testUint8Array, 0, foobarBuffer, execa);
test('stdio[*] option can be a Buffer', testUint8Array, 3, foobarBuffer, execa);
test('stdin option can be a Buffer - sync', testUint8Array, 0, foobarBuffer, execaSync);

const testNoUint8ArrayOutput = (t, fdNumber, execaMethod) => {
const testNoUint8ArrayOutput = (t, fdNumber, stdioOption, execaMethod) => {
t.throws(() => {
execaMethod('empty.js', getStdio(fdNumber, foobarUint8Array));
execaMethod('empty.js', getStdio(fdNumber, stdioOption));
}, {message: /cannot be a Uint8Array/});
};

test('stdout option cannot be a Uint8Array', testNoUint8ArrayOutput, 1, execa);
test('stderr option cannot be a Uint8Array', testNoUint8ArrayOutput, 2, execa);
test('stdout option cannot be a Uint8Array - sync', testNoUint8ArrayOutput, 1, execaSync);
test('stderr option cannot be a Uint8Array - sync', testNoUint8ArrayOutput, 2, execaSync);
test('stdout option cannot be a Uint8Array', testNoUint8ArrayOutput, 1, foobarUint8Array, execa);
test('stderr option cannot be a Uint8Array', testNoUint8ArrayOutput, 2, foobarUint8Array, execa);
test('stdout option cannot be a Uint8Array - sync', testNoUint8ArrayOutput, 1, foobarUint8Array, execaSync);
test('stderr option cannot be a Uint8Array - sync', testNoUint8ArrayOutput, 2, foobarUint8Array, execaSync);
test('stdout option cannot be a Buffer', testNoUint8ArrayOutput, 1, foobarBuffer, execa);
test('stderr option cannot be a Buffer', testNoUint8ArrayOutput, 2, foobarBuffer, execa);
test('stdout option cannot be a Buffer - sync', testNoUint8ArrayOutput, 1, foobarBuffer, execaSync);
test('stderr option cannot be a Buffer - sync', testNoUint8ArrayOutput, 2, foobarBuffer, execaSync);
10 changes: 9 additions & 1 deletion test/transform/generator-return.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 4 additions & 25 deletions test/transform/validate.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
import {Buffer} from 'node:buffer';
import test from 'ava';
import {execa, execaSync} from '../../index.js';
import {setFixtureDirectory} from '../helpers/fixtures-directory.js';
import {getStdio} from '../helpers/stdio.js';
import {foobarUint8Array, foobarBuffer, foobarObject} from '../helpers/input.js';
import {foobarUint8Array, foobarObject} from '../helpers/input.js';
import {serializeGenerator, getOutputGenerator, convertTransformToFinal} from '../helpers/generator.js';

setFixtureDirectory();

const getMessage = input => {
if (input === null || input === undefined) {
return 'not be called at all';
}

if (Buffer.isBuffer(input)) {
return 'not a buffer';
}

return 'a string or an Uint8Array';
};
const getMessage = input => input === null || input === undefined
? 'not be called at all'
: 'a string or an Uint8Array';

const lastInputGenerator = input => objectMode => [foobarUint8Array, getOutputGenerator(input)(objectMode)];
const inputGenerator = input => objectMode => [...lastInputGenerator(input)(objectMode), serializeGenerator(true)];
Expand All @@ -37,13 +28,6 @@ test('The last generator with result.stdio[*] as input cannot return an object e
test('Generators with result.stdout cannot return an object if not in objectMode', testGeneratorReturn, 1, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stderr cannot return an object if not in objectMode', testGeneratorReturn, 2, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stdio[*] as output cannot return an object if not in objectMode', testGeneratorReturn, 3, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stdin cannot return a Buffer if not in objectMode', testGeneratorReturn, 0, inputGenerator, foobarBuffer, false, true);
test('Generators with result.stdio[*] as input cannot return a Buffer if not in objectMode', testGeneratorReturn, 3, inputGenerator, foobarBuffer, false, true);
test('The last generator with result.stdin cannot return a Buffer even in objectMode', testGeneratorReturn, 0, lastInputGenerator, foobarBuffer, true, true);
test('The last generator with result.stdio[*] as input cannot return a Buffer even in objectMode', testGeneratorReturn, 3, lastInputGenerator, foobarBuffer, true, true);
test('Generators with result.stdout cannot return a Buffer if not in objectMode', testGeneratorReturn, 1, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stderr cannot return a Buffer if not in objectMode', testGeneratorReturn, 2, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stdio[*] as output cannot return a Buffer if not in objectMode', testGeneratorReturn, 3, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stdin cannot return null if not in objectMode', testGeneratorReturn, 0, inputGenerator, null, false, true);
test('Generators with result.stdin cannot return null if in objectMode', testGeneratorReturn, 0, inputGenerator, null, true, true);
test('Generators with result.stdout cannot return null if not in objectMode', testGeneratorReturn, 1, getOutputGenerator, null, false, false);
Expand All @@ -67,11 +51,6 @@ test('The last generator with result.stdin cannot return an object even in objec
test('Generators with result.stdout cannot return an object if not in objectMode, sync', testGeneratorReturnSync, 1, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stderr cannot return an object if not in objectMode, sync', testGeneratorReturnSync, 2, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stdio[*] as output cannot return an object if not in objectMode, sync', testGeneratorReturnSync, 3, getOutputGenerator, foobarObject, false, false);
test('Generators with result.stdin cannot return a Buffer if not in objectMode, sync', testGeneratorReturnSync, 0, inputGenerator, foobarBuffer, false, true);
test('The last generator with result.stdin cannot return a Buffer even in objectMode, sync', testGeneratorReturnSync, 0, lastInputGenerator, foobarBuffer, true, true);
test('Generators with result.stdout cannot return a Buffer if not in objectMode, sync', testGeneratorReturnSync, 1, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stderr cannot return a Buffer if not in objectMode, sync', testGeneratorReturnSync, 2, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stdio[*] as output cannot return a Buffer if not in objectMode, sync', testGeneratorReturnSync, 3, getOutputGenerator, foobarBuffer, false, false);
test('Generators with result.stdin cannot return null if not in objectMode, sync', testGeneratorReturnSync, 0, inputGenerator, null, false, true);
test('Generators with result.stdin cannot return null if in objectMode, sync', testGeneratorReturnSync, 0, inputGenerator, null, true, true);
test('Generators with result.stdout cannot return null if not in objectMode, sync', testGeneratorReturnSync, 1, getOutputGenerator, null, false, false);
Expand Down

0 comments on commit 40fdc75

Please sign in to comment.