Files
scriptc/tests/corpus/evolving-let-child-process.cjs
T
Chris Tate f521dc91b1 Compile three Node test shapes: a top-level return before declarations, nullable strictEqual operands, and a branch-assigned let
A top-level return in a CommonJS module compiles when declarations follow
it. When the return is taken, only code that already exists can observe the
bindings it skips: functions and classes created before the return, and
function declarations after it. A module where one of them reads a binding
declared after the return, or that assigns exports after it, still stops
with SC1090.

assert.strictEqual and assert.notStrictEqual compare a nullable number,
string or boolean (`number | null`, `string | null`) with a scalar, null or
undefined through the checked-dynamic SameValue compare, which reports
Node's failure messages. notStrictEqual of another nullable value, such as
`child.stdin`, against null or undefined tests the value's tag.

An initializer-less JavaScript `let` whose writes all agree also takes
their type when the writes are calls declared in the standard library, such
as `spawn(...)`, and at file scope. A runtime handle that a closure
captures takes the handle or undefined. Inside a nested function, a member
read on it (`c.address()`, `child.stdin`) reads the handle and throws
Node's TypeError while the binding is still undefined; other reads there
take the checked-dynamic value.
2026-10-29 20:51:09 -05:00

47 lines
1.5 KiB
JavaScript

// An initializer-less `let` assigned a child process on every branch keeps
// the child's type, including when callbacks read it, as Node's
// child_process tests do when they choose a command per platform.
const { spawn } = require('child_process');
let child;
if (process.platform === 'win32') child = spawn('cmd.exe', ['/c', 'echo', 'hi']);
else child = spawn('echo', ['hi']);
let text = '';
child.stdout.on('data', (chunk) => {
text += chunk;
});
let producer, consumer;
if (process.platform === 'win32') {
producer = spawn('cmd.exe', ['/c', 'echo', 'hello&&', 'echo', 'node']);
consumer = spawn('findstr', ['o']);
} else {
producer = spawn('printf', ['hello\nnode\nand\nworld\n']);
consumer = spawn('grep', ['o']);
}
producer.stdout.on('data', (data) => {
if (!consumer.stdin.write(data)) producer.stdout.pause();
});
consumer.stdin.on('drain', () => producer.stdout.resume());
producer.stdout.on('end', () => consumer.stdin.end());
let piped = '';
consumer.stdout.on('data', (data) => {
piped += data.toString('utf8', 0, data.length);
});
let quiet;
if (process.platform === 'win32') quiet = spawn('cmd.exe', ['/c', 'echo', 'quiet']);
else quiet = spawn('echo', ['quiet']);
quiet.stdout.setEncoding('utf8');
quiet.stdout.resume();
let count;
if (process.argv.length > 10) count = Math.max(1, 2);
else count = Math.min(3, 4);
console.log(count.toFixed(1));
process.on('exit', () => {
console.log(JSON.stringify(text), JSON.stringify(piped));
console.log(child.exitCode, producer.exitCode, consumer.exitCode, consumer.signalCode, quiet.exitCode);
});