Skip to content

Commit

Permalink
Fix multibyte sequence in output (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
ehmicky authored Aug 22, 2024
1 parent f720393 commit cb4116e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
9 changes: 5 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export default function nanoSpawn(command, rawArguments = [], rawOptions = {}) {

const getResult = async subprocess => {
const result = {};
bufferOutput(subprocess, result, 'stdout');
bufferOutput(subprocess, result, 'stderr');
bufferOutput(subprocess.stdout, result, 'stdout');
bufferOutput(subprocess.stderr, result, 'stderr');

try {
await once(subprocess, 'close');
Expand All @@ -43,9 +43,10 @@ const getResult = async subprocess => {
}
};

const bufferOutput = (subprocess, result, streamName) => {
const bufferOutput = (stream, result, streamName) => {
stream.setEncoding('utf8');
result[streamName] = '';
subprocess[streamName].on('data', chunk => {
stream.on('data', chunk => {
result[streamName] += chunk;
});
};
Expand Down
15 changes: 15 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {setTimeout} from 'node:timers/promises';
import test from 'ava';
import nanoSpawn from './index.js';

Expand Down Expand Up @@ -75,6 +76,20 @@ test('result.stderr strips Windows newline', async t => {
t.is(stderr, '.');
});

const multibyteString = '.\u{1F984}.';
const multibyteUint8Array = new TextEncoder().encode(multibyteString);
const multibyteFirstHalf = multibyteUint8Array.slice(0, 3);
const multibyteSecondHalf = multibyteUint8Array.slice(3);

test.serial('result.stdout works with multibyte sequences', async t => {
const promise = nanoSpawn('node', ['-e', 'process.stdin.pipe(process.stdout)']);
promise.subprocess.stdin.write(multibyteFirstHalf);
await setTimeout(1e2);
promise.subprocess.stdin.end(multibyteSecondHalf);
const {stdout} = await promise;
t.is(stdout, multibyteString);
});

test('promise.stdout can be iterated', async t => {
const promise = nanoSpawn('node', ['-e', 'console.log("a\\nb")']);

Expand Down
5 changes: 2 additions & 3 deletions utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ export async function * combineAsyncIterators(iterator1, iterator2) {
}
}

export async function * lineIterator(stream) {
stream.setEncoding('utf8');
export async function * lineIterator(iterable) {
let buffer = '';
for await (const chunk of stream) {
for await (const chunk of iterable) {
const lines = `${buffer}${chunk}`.split(/\r?\n/);
buffer = lines.pop(); // Keep last line in buffer as it may not be complete
yield * lines;
Expand Down

0 comments on commit cb4116e

Please sign in to comment.