Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,9 @@
'use strict';
require('../common');
process.env.TERM = 'dumb';
console.log({ foo: 'bar' });
console.dir({ foo: 'bar' });
console.log('%s q', 'string');
console.log('%o with object format param', { foo: 'bar' });

View File

@ -0,0 +1,4 @@
{ foo: 'bar' }
{ foo: 'bar' }
string q
{ foo: 'bar' } with object format param

View File

@ -0,0 +1,23 @@
'use strict';
require('../common');
const vm = require('vm');
// Make this test OS-independent by overriding stdio getColorDepth().
process.stdout.getColorDepth = () => 8;
process.stderr.getColorDepth = () => 8;
Error.stackTraceLimit = Infinity;
console.log({ foo: 'bar' });
console.log('%s q', 'string');
console.log('%o with object format param', { foo: 'bar' });
console.log(
new Error('test\n at abc (../fixtures/node_modules/bar.js:4:4)\nfoobar'),
);
try {
require('../fixtures/node_modules/node_modules/bar.js');
} catch (err) {
console.log(err);
}
vm.runInThisContext('console.log(new Error())');

View File

@ -0,0 +1,50 @@
{ foo: [32m'bar'[39m }
string q
{ foo: [32m'bar'[39m } with object format param
Error: test
at abc (../fixtures/node_modules/bar.js:4:4)
foobar
at Object.<anonymous> [90m(*[39m*console_colors.js:*:*[90m)[39m
[90m at * (node:internal*:*:*)[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
Error: Should not ever get here.
at Object.<anonymous> [90m(*node_modules*[4m*node_modules*[24m*bar.js:*:*[90m)[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
at Object.<anonymous> [90m(*console_colors.js:*:*[90m)[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
Error
at evalmachine.<anonymous>:*:*
[90m at Script.runInThisContext (node:vm:*:*)[39m
[90m at Object.runInThisContext (node:vm:*:*)[39m
at Object.<anonymous> [90m(*[39m*console_colors.js:*:*[90m)[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m

View File

@ -0,0 +1,19 @@
// https://github.com/nodejs/node/issues/6456#issuecomment-219320599
// https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd
'use strict';
const common = require('../common');
// 1000 bytes wrapped at 50 columns
// \n turns into a double-byte character
// (48 + {2}) * 20 = 1000
let out = `${'o'.repeat(48)}\n`.repeat(20);
// Add the remaining 24 bytes and terminate with an 'O'.
// This results in 1025 bytes, just enough to overflow the 1kb OS X TTY buffer.
out += `${'o'.repeat(24)}O`;
// In AIX, the child exits even before the python parent
// can setup the readloop. Provide a reasonable delay.
setTimeout(function() {
process.stdout.write(out);
process.exit(0);
}, common.isAIX ? 200 : 0);

View File

@ -0,0 +1,21 @@
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooO

View File

@ -0,0 +1,21 @@
// https://github.com/nodejs/node/issues/6456#issuecomment-219320599
// https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd
'use strict';
const common = require('../common');
// 1000 bytes wrapped at 50 columns
// \n turns into a double-byte character
// (48 + {2}) * 20 = 1000
let out = `${'o'.repeat(48)}\n`.repeat(20);
// Add the remaining 24 bytes and terminate with an 'O'.
// This results in 1025 bytes, just enough to overflow the 1kb OS X TTY buffer.
out += `${'o'.repeat(24)}O`;
const err = '__This is some stderr__';
// In AIX, the child exits even before the python parent
// can setup the readloop. Provide a reasonable delay.
setTimeout(function() {
process.stdout.write(out);
process.stderr.write(err);
}, common.isAIX ? 200 : 0);

View File

@ -0,0 +1,21 @@
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
oooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooO__This is some stderr__

View File

@ -0,0 +1,6 @@
prefix pseudo-tty
[$system==solaris]
# https://github.com/nodejs/node/pull/16225 - `ioctl(fd, TIOCGWINSZ)` seems
# to fail with EINVAL on SmartOS when `fd` is a pty from python's pty module.
test-tty-stdout-resize : FAIL, PASS

View File

@ -0,0 +1,21 @@
'use strict';
require('../common');
process.env.TERM = 'dumb';
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.write('text');
rl.write(null, { ctrl: true, name: 'u' });
rl.write(null, { name: 'return' });
rl.write('text');
rl.write(null, { name: 'backspace' });
rl.write(null, { name: 'escape' });
rl.write(null, { name: 'enter' });
rl.write('text');
rl.write(null, { ctrl: true, name: 'c' });

View File

@ -0,0 +1,3 @@
text
text
text

View File

@ -0,0 +1,30 @@
// Flags: --expose-internals --no-warnings
'use strict';
require('../common');
const { internalBinding } = require('internal/test/binding');
const { TTY, isTTY } = internalBinding('tty_wrap');
const strictEqual = require('assert').strictEqual;
strictEqual(isTTY(0), true, 'fd 0 is not a TTY');
const handle = new TTY(0);
handle.readStart();
handle.onread = () => {};
function isHandleActive(handle) {
return process._getActiveHandles().some((active) => active === handle);
}
strictEqual(isHandleActive(handle), true, 'TTY handle not initially active');
handle.unref();
strictEqual(isHandleActive(handle), false, 'TTY handle active after unref()');
handle.ref();
strictEqual(isHandleActive(handle), true, 'TTY handle inactive after ref()');
handle.unref();

View File

@ -0,0 +1,38 @@
'use strict';
const common = require('../common');
const process = require('process');
process.env.TERM = 'dumb';
const repl = require('repl');
const ArrayStream = require('../common/arraystream');
repl.start('> ');
// Verify <ctrl> + D support.
{
const stream = new ArrayStream();
const replServer = new repl.REPLServer({
prompt: '> ',
terminal: true,
input: stream,
output: process.stdout,
useColors: false,
});
replServer.on('close', common.mustCall());
// Verify that <ctrl> + R or <ctrl> + C does not trigger the reverse search.
replServer.write(null, { ctrl: true, name: 'r' });
replServer.write(null, { ctrl: true, name: 's' });
replServer.write(null, { ctrl: true, name: 'd' });
}
process.stdin.push('conso'); // No completion preview.
process.stdin.push('le.log("foo")\n');
process.stdin.push('1 + 2'); // No input preview.
process.stdin.push('\n');
process.stdin.push('"str"\n');
process.stdin.push('console.dir({ a: 1 })\n');
process.stdin.push('{ a: 1 }\n');
process.stdin.push('\n');
process.stdin.push('.exit\n');

View File

@ -0,0 +1,15 @@
> >
console.log("foo")
foo
undefined
> 1 + 2
3
> "str"
'str'
> console.dir({ a: 1 })
{ a: 1 }
undefined
> { a: 1 }
{ a: 1 }
>
> .exit

View File

@ -0,0 +1,9 @@
'use strict';
require('../common');
const assert = require('assert');
process.stdin.setRawMode(true);
assert.strictEqual(process.stdin.isRaw, true);
process.stdin.setRawMode(false);
assert.strictEqual(process.stdin.isRaw, false);

View File

View File

@ -0,0 +1,70 @@
'use strict';
require('../common');
const assert = require('assert').strict;
function setup() {
process.env.FORCE_COLOR = '1';
delete process.env.NODE_DISABLE_COLORS;
delete process.env.NO_COLOR;
}
assert.throws(() => {
setup();
assert.deepStrictEqual([1, 2, 2, 2, 2], [2, 2, 2, 2, 2]);
}, (err) => {
const expected = 'Expected values to be strictly deep-equal:\n' +
'\x1B[32m+ actual\x1B[39m \x1B[31m- expected\x1B[39m\n' +
'\n' +
'\x1B[39m [\n' +
'\x1B[32m+\x1B[39m 1,\n' +
'\x1B[39m 2,\n' +
'\x1B[39m 2,\n' +
'\x1B[39m 2,\n' +
'\x1B[39m 2,\n' +
'\x1B[31m-\x1B[39m 2\n' +
'\x1B[39m ]\n';
assert.strictEqual(err.message, expected);
return true;
});
{
assert.throws(() => {
setup();
assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3, d: 5 }, { z: 4, b: 5 });
}, (err) => {
const expected = 'Expected values to be partially and strictly deep-equal:\n' +
'\x1B[90mactual\x1B[39m \x1B[31m- expected\x1B[39m\n' +
'\n' +
'\x1B[39m {\n' +
'\x1B[90m a: 1,\x1B[39m\n' +
'\x1B[90m b: 2,\x1B[39m\n' +
'\x1B[90m c: 3,\x1B[39m\n' +
'\x1B[90m d: 5\x1B[39m\n' +
'\x1B[31m-\x1B[39m b: 5,\n' +
'\x1B[31m-\x1B[39m z: 4\n' +
'\x1B[39m }\n';
assert.strictEqual(err.message, expected);
return true;
});
assert.throws(() => {
setup();
assert.partialDeepStrictEqual([1, 2, 3, 5], [4, 5]);
}, (err) => {
const expected = 'Expected values to be partially and strictly deep-equal:\n' +
'\x1B[90mactual\x1B[39m \x1B[31m- expected\x1B[39m\n' +
'\n' +
'\x1B[39m [\n' +
'\x1B[90m 1,\x1B[39m\n' +
'\x1B[90m 2,\x1B[39m\n' +
'\x1B[90m 3,\x1B[39m\n' +
'\x1B[31m-\x1B[39m 4,\n' +
'\x1B[39m 5\n' +
'\x1B[39m ]\n';
assert.strictEqual(err.message, expected);
return true;
});
}

View File

View File

@ -0,0 +1,35 @@
'use strict';
require('../common');
const assert = require('assert').strict;
process.env.NODE_DISABLE_COLORS = true;
assert.throws(
() => {
assert.deepStrictEqual({}, { foo: 'bar' });
},
{
message: 'Expected values to be strictly deep-equal:\n' +
'+ actual - expected\n' +
'\n' +
'+ {}\n' +
'- {\n' +
'- foo: \'bar\'\n' +
'- }\n',
});
{
assert.throws(
() => {
assert.partialDeepStrictEqual({}, { foo: 'bar' });
},
{
message: 'Expected values to be partially and strictly deep-equal:\n' +
'+ actual - expected\n' +
'\n' +
'+ {}\n' +
'- {\n' +
"- foo: 'bar'\n" +
'- }\n',
});
}

View File

View File

@ -0,0 +1,40 @@
'use strict';
require('../common');
const assert = require('assert');
process.env.NODE_DISABLE_COLORS = '1';
// Does not show the indicator when the terminal is too narrow
process.stderr.columns = 20;
assert.throws(
() => { assert.strictEqual('123456789ABCDEFGHI', '1!3!5!7!9!BC!!!GHI'); },
(err) => !err.message.includes('^'),
);
// Does not show the indicator because the first difference is in the first 2 chars
process.stderr.columns = 80;
assert.throws(
() => { assert.strictEqual('123456789ABCDEFGHI', '1!3!5!7!9!BC!!!GHI'); },
{
message: 'Expected values to be strictly equal:\n' +
'+ actual - expected\n' +
'\n' +
"+ '123456789ABCDEFGHI'\n" +
"- '1!3!5!7!9!BC!!!GHI'\n",
},
);
// Show the indicator because the first difference is in the 3 char
process.stderr.columns = 80;
assert.throws(
() => { assert.strictEqual('123456789ABCDEFGHI', '12!!5!7!9!BC!!!GHI'); },
{
message: 'Expected values to be strictly equal:\n' +
'+ actual - expected\n' +
'\n' +
"+ '123456789ABCDEFGHI'\n" +
"- '12!!5!7!9!BC!!!GHI'\n" +
' ^\n',
},
);

View File

@ -0,0 +1,45 @@
// Flags: --expose-internals --no-warnings
'use strict';
// See also test/sequential/test-async-wrap-getasyncid.js
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const { TTYWRAP } = internalBinding('async_wrap').Providers;
const tty_wrap = internalBinding('tty_wrap');
const providers = { TTYWRAP };
// Make sure that the TTYWRAP Provider is tested.
{
const hooks = require('async_hooks').createHook({
init(id, type) {
if (type === 'NONE')
throw new Error('received a provider type of NONE');
delete providers[type];
},
}).enable();
process.on('beforeExit', common.mustCall(() => {
process.removeAllListeners('uncaughtException');
hooks.disable();
const objKeys = Object.keys(providers);
if (objKeys.length > 0)
process._rawDebug(objKeys);
assert.strictEqual(objKeys.length, 0);
}));
}
function testInitialized(req, ctor_name) {
assert.strictEqual(typeof req.getAsyncId, 'function');
assert(Number.isSafeInteger(req.getAsyncId()));
assert(req.getAsyncId() > 0);
assert.strictEqual(req.constructor.name, ctor_name);
}
{
const ttyFd = common.getTTYfd();
const handle = new tty_wrap.TTY(ttyFd, false);
testInitialized(handle, 'TTY');
}

View File

@ -0,0 +1,10 @@
'use strict';
require('../common');
const { inspect } = require('util');
inspect.defaultOptions.colors = true;
const err = new TypeError('foobar');
err.bla = true;
throw err;

View File

@ -0,0 +1,18 @@
*test-fatal-error.js:*
throw err;
^
TypeError: foobar
at Object.<anonymous> [90m(*test-fatal-error.js:*:*[90m)[39m
[90m at *(node:internal*loader:*:*)[39m
[90m at *(node:internal*loader:*:*)[39m
[90m at *(node:internal*loader:*:*)[39m
[90m at *(node:internal*loader:*:*)[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m
[90m at *[39m {
bla: [33mtrue[39m
}
Node.js *

View File

@ -0,0 +1,23 @@
// Flags: --expose-internals --no-warnings
'use strict';
// See also test/parallel/test-handle-wrap-hasref.js
const common = require('../common');
const strictEqual = require('assert').strictEqual;
const ReadStream = require('tty').ReadStream;
const tty = new ReadStream(0);
const { internalBinding } = require('internal/test/binding');
const isTTY = internalBinding('tty_wrap').isTTY;
strictEqual(isTTY(0), true, 'tty_wrap: stdin is not a TTY');
strictEqual(tty._handle.hasRef(),
true, 'tty_wrap: not initially refed');
tty.unref();
strictEqual(tty._handle.hasRef(),
false, 'tty_wrap: unref() ineffective');
tty.ref();
strictEqual(tty._handle.hasRef(),
true, 'tty_wrap: ref() ineffective');
tty._handle.close(common.mustCall(() =>
strictEqual(tty._handle.hasRef(),
false, 'tty_wrap: not unrefed on close')));

View File

@ -0,0 +1,29 @@
'use strict';
const common = require('../common');
const assert = require('assert');
// This test ensures that Node.js will not ignore tty 'readable' subscribers
// when it's the only tty subscriber and the only thing keeping event loop alive
// https://github.com/nodejs/node/issues/20503
process.stdin.setEncoding('utf8');
const expectedInput = ['foo', 'bar', null];
process.stdin.on('readable', common.mustCall(function() {
const data = process.stdin.read();
assert.strictEqual(data, expectedInput.shift());
}, 3)); // first 2 data, then end
process.stdin.on('end', common.mustCall());
setTimeout(() => {
process.stdin.push('foo');
process.nextTick(() => {
process.stdin.push('bar');
process.nextTick(() => {
process.stdin.push(null);
});
});
}, 1);

View File

@ -0,0 +1,14 @@
'use strict';
require('../common');
const fixtures = require('../common/fixtures');
const { execFileSync } = require('child_process');
execFileSync(process.execPath, {
encoding: 'utf8',
stdio: 'inherit',
env: {
...process.env,
NODE_REPL_EXTERNAL_MODULE: fixtures.path('external-repl-module.js'),
},
});

View File

@ -0,0 +1 @@
42

View File

@ -0,0 +1,18 @@
'use strict';
require('../common');
const child_process = require('child_process');
// Tests that exiting through process.exit() resets the TTY mode.
child_process.spawnSync(process.execPath, [
'-e', 'process.stdin.setRawMode(true); process.exit(0)',
], { stdio: 'inherit' });
const { stdout } = child_process.spawnSync('stty', {
stdio: ['inherit', 'pipe', 'inherit'],
encoding: 'utf8',
});
if (stdout.match(/-echo\b/)) {
console.log(stdout);
}

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
const child_process = require('child_process');
// Tests that exiting through a catchable signal resets the TTY mode.
const proc = child_process.spawn(process.execPath, [
'-e', 'process.stdin.setRawMode(true); console.log("Y"); while(true) {}',
], { stdio: ['inherit', 'pipe', 'inherit'] });
proc.stdout.on('data', common.mustCall(() => {
proc.kill('SIGINT');
}));
proc.on('exit', common.mustCall(() => {
const { stdout } = child_process.spawnSync('stty', {
stdio: ['inherit', 'pipe', 'inherit'],
encoding: 'utf8',
});
if (stdout.match(/-echo\b/)) {
console.log(stdout);
}
}));

View File

@ -0,0 +1,19 @@
'use strict';
require('../common');
const child_process = require('child_process');
// Tests that exiting through normal means resets the TTY mode.
// Refs: https://github.com/nodejs/node/issues/21020
child_process.spawnSync(process.execPath, [
'-e', 'process.stdin.setRawMode(true)',
], { stdio: 'inherit' });
const { stdout } = child_process.spawnSync('stty', {
stdio: ['inherit', 'pipe', 'inherit'],
encoding: 'utf8',
});
if (stdout.match(/-echo\b/)) {
console.log(stdout);
}

View File

@ -0,0 +1,34 @@
'use strict';
const common = require('../common');
const originalRefreshSizeStderr = process.stderr._refreshSize;
const originalRefreshSizeStdout = process.stdout._refreshSize;
const wrap = (fn, ioStream, string) => {
const wrapped = common.mustCall(() => {
// The console.log() call prints a string that is in the .out file. In other
// words, the console.log() is part of the test, not extraneous debugging.
console.log(string);
try {
fn.call(ioStream);
} catch (e) {
// EINVAL happens on SmartOS if emulation is incomplete
if (!common.isSunOS || e.code !== 'EINVAL')
throw e;
}
});
return wrapped;
};
process.stderr._refreshSize = wrap(originalRefreshSizeStderr,
process.stderr,
'calling stderr._refreshSize');
process.stdout._refreshSize = wrap(originalRefreshSizeStdout,
process.stdout,
'calling stdout._refreshSize');
// In AIX, the child exits even before the python parent
// can setup the readloop. Provide a reasonable delay.
setTimeout(function() {
process.emit('SIGWINCH');
}, common.isAIX ? 200 : 0);

View File

@ -0,0 +1,2 @@
calling stderr._refreshSize
calling stdout._refreshSize

View File

@ -0,0 +1,3 @@
'use strict';
require('../common');
process.stdin.end('foobar\n');

View File

@ -0,0 +1 @@
foobar

View File

@ -0,0 +1,2 @@
Hello!


View File

@ -0,0 +1,3 @@
'use strict';
const common = require('../common');
process.stderr.on('data', common.mustCall(console.log));

View File

@ -0,0 +1,2 @@
Hello!
<Buffer 48 65 6c 6c 6f 21 0a>

View File

@ -0,0 +1,16 @@
'use strict';
// Env: A_SET_ENV_VAR=A_SET_ENV_VAR_VALUE B_SET_ENV_VAR=B_SET_ENV_VAR_VALUE
// Flags: --test-isolation=none --expose-internals
require('../common');
const assert = require('node:assert');
// This test verifies that the Python test runner can set environment variables
// via comments in the test file, similar to how we set flags via comments.
// Ref: https://github.com/nodejs/node/issues/58179
assert.strictEqual(process.env.A_SET_ENV_VAR, 'A_SET_ENV_VAR_VALUE');
assert.strictEqual(process.env.B_SET_ENV_VAR, 'B_SET_ENV_VAR_VALUE');
// Check interop with flags
const flag = require('internal/options').getOptionValue('--test-isolation');
assert.strictEqual(flag, 'none');

View File

@ -0,0 +1,39 @@
'use strict';
const { mustCall } = require('../common');
const childProcess = require('child_process');
const assert = require('assert');
if (process.env.CHILD === 'true') {
main();
} else {
// Use inherited stdio child process to prevent test tools from determining
// the case as crashed from SIGINT
const cp = childProcess.spawn(
process.execPath,
['--trace-sigint', __filename],
{
env: { ...process.env, CHILD: 'true' },
stdio: 'inherit',
});
cp.on('exit', mustCall((code, signal) => {
assert.strictEqual(signal, null);
assert.strictEqual(code, 0);
}));
}
function main() {
// Deactivate colors even if the tty does support colors.
process.env.NODE_DISABLE_COLORS = '1';
const noop = mustCall(() => {
process.exit(0);
});
process.on('SIGINT', noop);
// Try testing re-add 'SIGINT' listeners
process.removeListener('SIGINT', noop);
process.on('SIGINT', noop);
process.kill(process.pid, 'SIGINT');
setTimeout(() => { assert.fail('unreachable path'); }, 10 * 1000);
}

View File

@ -0,0 +1,32 @@
'use strict';
const { platformTimeout, mustCall } = require('../common');
const childProcess = require('child_process');
const assert = require('assert');
if (process.env.CHILD === 'true') {
main();
} else {
// Use inherited stdio child process to prevent test tools from determining
// the case as crashed from SIGINT
const cp = childProcess.spawn(
process.execPath,
['--trace-sigint', __filename],
{
env: { ...process.env, CHILD: 'true' },
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
});
cp.on('message', mustCall(() => {
setTimeout(() => cp.kill('SIGINT'), platformTimeout(100));
}));
cp.on('exit', mustCall((code, signal) => {
assert.strictEqual(signal, 'SIGINT');
assert.strictEqual(code, null);
}));
}
function main() {
// Deactivate colors even if the tty does support colors.
process.env.NODE_DISABLE_COLORS = '1';
process.channel.ref(); // Keep event loop alive until the signal is received.
process.send('ready');
}

View File

@ -0,0 +1 @@
KEYBOARD_INTERRUPT: Script execution was interrupted by `SIGINT`

View File

@ -0,0 +1,30 @@
'use strict';
const { mustCall } = require('../common');
const childProcess = require('child_process');
const assert = require('assert');
if (process.env.CHILD === 'true') {
main();
} else {
// Use inherited stdio child process to prevent test tools from determining
// the case as crashed from SIGINT
const cp = childProcess.spawn(
process.execPath,
['--trace-sigint', __filename],
{
env: { ...process.env, CHILD: 'true' },
stdio: 'inherit',
});
cp.on('exit', mustCall((code, signal) => {
assert.strictEqual(signal, 'SIGINT');
assert.strictEqual(code, null);
}));
}
function main() {
// Deactivate colors even if the tty does support colors.
process.env.NODE_DISABLE_COLORS = '1';
process.kill(process.pid, 'SIGINT');
while (true);
}

View File

@ -0,0 +1,11 @@
KEYBOARD_INTERRUPT: Script execution was interrupted by `SIGINT`
at main (*/test-trace-sigint.js:*)
at */test-trace-sigint.js:*
at *
at *
at *
at *
at *
at *
at *
at *

View File

@ -0,0 +1,8 @@
'use strict';
require('../common');
process.env.NODE_DISABLE_COLORS = '1';
process.env.FORCE_COLOR = '3';
console.log();

View File

@ -0,0 +1,3 @@
(node:*) Warning: The 'NODE_DISABLE_COLORS' env is ignored due to the 'FORCE_COLOR' env being set.
(Use `* --trace-warnings ...` to show where the warning was created)

View File

@ -0,0 +1,9 @@
'use strict';
require('../common');
process.env.NO_COLOR = '1';
process.env.NODE_DISABLE_COLORS = '1';
process.env.FORCE_COLOR = '3';
console.log();

View File

@ -0,0 +1,3 @@
(node:*) Warning: The 'NODE_DISABLE_COLORS' and 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
(Use `* --trace-warnings ...` to show where the warning was created)

View File

@ -0,0 +1,110 @@
'use strict';
const common = require('../common');
const assert = require('assert').strict;
const { WriteStream } = require('tty');
const { inspect } = require('util');
const fd = common.getTTYfd();
const writeStream = new WriteStream(fd);
{
const depth = writeStream.getColorDepth();
assert.strictEqual(typeof depth, 'number');
assert(depth >= 1 && depth <= 24);
const support = writeStream.hasColors();
assert.strictEqual(support, depth !== 1);
}
// Validate invalid input.
[true, null, () => {}, Symbol(), 5n].forEach((input) => {
assert.throws(
() => writeStream.hasColors(input),
{ code: 'ERR_INVALID_ARG_TYPE' },
);
});
[-1, 1].forEach((input) => {
assert.throws(
() => writeStream.hasColors(input),
{ code: 'ERR_OUT_OF_RANGE' },
);
});
// Check different environment variables.
[
[{ COLORTERM: '1' }, 4],
[{ COLORTERM: 'truecolor' }, 24],
[{ COLORTERM: '24bit' }, 24],
[{ TMUX: '1' }, 24],
[{ CI: '1' }, 1],
[{ CI: '', APPVEYOR: '1' }, 8],
[{ CI: '1', BUILDKITE: '' }, 8],
[{ CI: '1', CI_NAME: 'codeship' }, 8],
[{ CI: '1', CIRCLECI: '1' }, 24],
[{ CI: '1', DRONE: '' }, 8],
[{ CI: '1', GITEA_ACTIONS: '' }, 24],
[{ CI: '1', GITHUB_ACTIONS: '' }, 24],
[{ CI: '1', GITLAB_CI: '1' }, 8],
[{ CI: '1', TRAVIS: '1' }, 8],
[{ CI: '', TRAVIS: '' }, 8],
[{ TEAMCITY_VERSION: '1.0.0' }, 1],
[{ TEAMCITY_VERSION: '9.11.0' }, 4],
[{ TERM_PROGRAM: 'iTerm.app' }, 8],
[{ TERM_PROGRAM: 'iTerm.app', TERM_PROGRAM_VERSION: '3.0' }, 24],
[{ TERM_PROGRAM: 'iTerm.app', TERM_PROGRAM_VERSION: '2.0' }, 8],
[{ TERM_PROGRAM: 'HyperTerm' }, 24],
[{ TERM_PROGRAM: 'Hyper' }, 1],
[{ TERM_PROGRAM: 'MacTerm' }, 24],
[{ TERM_PROGRAM: 'Apple_Terminal' }, 8],
[{ TERM: 'ansi' }, 4],
[{ TERM: 'ANSI' }, 4],
[{ TERM: 'color' }, 4],
[{ TERM: 'color', NODE_DISABLE_COLORS: '1' }, 1],
[{ TERM: 'console' }, 4],
[{ TERM: 'direct' }, 4],
[{ TERM: 'dumb' }, 1],
[{ TERM: 'dumb', COLORTERM: '1' }, 1],
[{ TERM: 'fail' }, 1],
[{ TERM: 'linux' }, 4],
[{ TERM: 'terminator' }, 24],
[{ TERM: 'vt100' }, 4],
[{ TERM: 'vt220' }, 4],
[{ TERM: 'xterm-256' }, 8],
[{ TERM: 'xterm-kitty' }, 24],
[{ TERM: 'xterm-truecolor' }, 24],
[{ COLORTERM: '24bit', FORCE_COLOR: '' }, 4],
[{ NO_COLOR: '1', FORCE_COLOR: '2' }, 8],
[{ NODE_DISABLE_COLORS: '1', FORCE_COLOR: '3' }, 24],
[{ NO_COLOR: '1', COLORTERM: '24bit' }, 1],
[{ NO_COLOR: '', COLORTERM: '24bit' }, 1],
[{ TMUX: '1', FORCE_COLOR: 0 }, 1],
[{ NO_COLOR: 'true', FORCE_COLOR: 0, COLORTERM: 'truecolor' }, 1],
[{ TERM: 'xterm-256color', COLORTERM: 'truecolor' }, 24],
[{ TF_BUILD: '', AGENT_NAME: '' }, 4],
].forEach(([env, depth], i) => {
const actual = writeStream.getColorDepth(env);
assert.strictEqual(
actual,
depth,
`i: ${i}, expected: ${depth}, ` +
`actual: ${actual}, env: ${inspect(env)}`,
);
const colors = 2 ** actual;
assert(writeStream.hasColors(colors, env));
assert(!writeStream.hasColors(colors + 1, env));
assert(depth >= 4 ? writeStream.hasColors(env) : !writeStream.hasColors(env));
});
// OS settings
{
const platform = Object.getOwnPropertyDescriptor(process, 'platform');
const [ value, depth1, depth2 ] = process.platform !== 'win32' ?
['win32', 1, 4] : ['linux', 4, 1];
assert.strictEqual(writeStream.getColorDepth({}), depth1);
Object.defineProperty(process, 'platform', { value });
assert.strictEqual(writeStream.getColorDepth({}), depth2);
Object.defineProperty(process, 'platform', platform);
}

View File

@ -0,0 +1,2 @@
(node:*) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
(Use `* --trace-warnings ...` to show where the warning was created)

View File

@ -0,0 +1,18 @@
'use strict';
require('../common');
const { strictEqual } = require('assert');
const { isatty } = require('tty');
strictEqual(isatty(0), true, 'stdin reported to not be a tty, but it is');
strictEqual(isatty(1), true, 'stdout reported to not be a tty, but it is');
strictEqual(isatty(2), true, 'stderr reported to not be a tty, but it is');
strictEqual(isatty(-1), false, '-1 reported to be a tty, but it is not');
strictEqual(isatty(55555), false, '55555 reported to be a tty, but it is not');
strictEqual(isatty(2 ** 31), false, '2^31 reported to be a tty, but it is not');
strictEqual(isatty(1.1), false, '1.1 reported to be a tty, but it is not');
strictEqual(isatty('1'), false, '\'1\' reported to be a tty, but it is not');
strictEqual(isatty({}), false, '{} reported to be a tty, but it is not');
strictEqual(isatty(() => {}), false,
'() => {} reported to be a tty, but it is not');

View File

View File

@ -0,0 +1,8 @@
'use strict';
require('../common');
// This tests verifies that process.stdin.end() does not
// crash the process with ENOTCONN
process.stdin.end();

View File

@ -0,0 +1,7 @@
'use strict';
require('../common');
// This test ensures that Node.js doesn't crash on `process.stdin.emit("end")`.
// https://github.com/nodejs/node/issues/1068
process.stdin.emit('end');

View File

View File

@ -0,0 +1,4 @@
'use strict';
require('../common');
process.stdout.end();

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,11 @@
'use strict';
const { mustCall } = require('../common');
const { notStrictEqual } = require('assert');
// tty.WriteStream#_refreshSize() only emits the 'resize' event when the
// window dimensions change. We cannot influence that from the script
// but we can set the old values to something exceedingly unlikely.
process.stdout.columns = 9001;
process.stdout.on('resize', mustCall());
process.kill(process.pid, 'SIGWINCH');
setImmediate(mustCall(() => notStrictEqual(process.stdout.columns, 9001)));

View File

@ -0,0 +1,21 @@
'use strict';
require('../common');
const assert = require('assert');
const { ReadStream, WriteStream } = require('tty');
{
// Verify that tty.ReadStream can be constructed without new.
const stream = ReadStream(0);
stream.unref();
assert(stream instanceof ReadStream);
assert.strictEqual(stream.isTTY, true);
}
{
// Verify that tty.WriteStream can be constructed without new.
const stream = WriteStream(1);
assert(stream instanceof WriteStream);
assert.strictEqual(stream.isTTY, true);
}

View File

@ -0,0 +1,87 @@
// Flags: --expose-internals --no-warnings
'use strict';
const common = require('../common');
const assert = require('assert');
const { WriteStream } = require('tty');
const { internalBinding } = require('internal/test/binding');
const { TTY } = internalBinding('tty_wrap');
const getWindowSize = TTY.prototype.getWindowSize;
function monkeyPatchGetWindowSize(fn) {
TTY.prototype.getWindowSize = function() {
TTY.prototype.getWindowSize = getWindowSize;
return fn.apply(this, arguments);
};
}
{
// tty.WriteStream constructor does not define columns and rows if an error
// occurs while retrieving the window size from the handle.
monkeyPatchGetWindowSize(function() {
return -1;
});
const stream = WriteStream(1);
assert(stream instanceof WriteStream);
assert.strictEqual(stream.columns, undefined);
assert.strictEqual(stream.rows, undefined);
}
{
// _refreshSize() emits an error if an error occurs while retrieving the
// window size from the handle.
const stream = WriteStream(1);
stream.on('error', common.mustCall((err) => {
assert.strictEqual(err.syscall, 'getWindowSize');
}));
monkeyPatchGetWindowSize(function() {
return -1;
});
stream._refreshSize();
}
{
// _refreshSize() emits a 'resize' event when the window size changes.
monkeyPatchGetWindowSize(function(size) {
size[0] = 80;
size[1] = 24;
return 0;
});
const stream = WriteStream(1);
stream.on('resize', common.mustCall(() => {
assert.strictEqual(stream.columns, 82);
assert.strictEqual(stream.rows, 26);
}));
assert.strictEqual(stream.columns, 80);
assert.strictEqual(stream.rows, 24);
monkeyPatchGetWindowSize(function(size) {
size[0] = 82;
size[1] = 26;
return 0;
});
stream._refreshSize();
}
{
// WriteStream.prototype.getWindowSize() returns the current columns and rows.
monkeyPatchGetWindowSize(function(size) {
size[0] = 99;
size[1] = 32;
return 0;
});
const stream = WriteStream(1);
assert.strictEqual(stream.columns, 99);
assert.strictEqual(stream.rows, 32);
assert.deepStrictEqual(stream.getWindowSize(), [99, 32]);
}

View File

View File

@ -0,0 +1,13 @@
// Flags: --expose-internals --no-warnings
'use strict';
require('../common');
const { internalBinding } = require('internal/test/binding');
const { TTY } = internalBinding('tty_wrap');
const { WriteWrap } = internalBinding('stream_wrap');
const handle = new TTY(1);
const req = new WriteWrap();
handle.writeBuffer(req, Buffer.from('hello world 1\n'));
handle.writeBuffer(req, Buffer.from('hello world 2\n'));

View File

@ -0,0 +1,2 @@
hello world 1
hello world 2

178
test/pseudo-tty/testcfg.py Normal file
View File

@ -0,0 +1,178 @@
# Copyright 2008 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import print_function
import test
import os
from os.path import join, exists, basename, dirname, isdir
import re
import sys
import utils
from functools import reduce
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
PTY_HELPER = join(dirname(__file__), '../../tools/pseudo-tty.py')
ENV_PATTERN = re.compile(r"//\s+Env:(.*)")
class TTYTestCase(test.TestCase):
def __init__(self, path, file, expected, input_arg, arch, mode, context, config):
super(TTYTestCase, self).__init__(context, path, arch, mode)
self.file = file
self.expected = expected
self.input = input_arg
self.config = config
self.arch = arch
self.mode = mode
self.parallel = True
def IgnoreLine(self, str_arg):
"""Ignore empty lines and valgrind output."""
if not str_arg.strip(): return True
else: return str_arg.startswith('==') or str_arg.startswith('**')
def IsFailureOutput(self, output):
f = open(self.expected)
# Convert output lines to regexps that we can match
env = { 'basename': basename(self.file) }
patterns = [ ]
for line in f:
if not line.strip():
continue
pattern = re.escape(line.rstrip() % env)
pattern = pattern.replace('\\*', '.*')
pattern = '^%s$' % pattern
patterns.append(pattern)
# Compare actual output with the expected
raw_lines = (output.stdout + output.stderr).split('\n')
outlines = [ s.rstrip() for s in raw_lines if not self.IgnoreLine(s) ]
if len(outlines) != len(patterns):
print(" length differs.")
print("expect=%d" % len(patterns))
print("actual=%d" % len(outlines))
print("patterns:")
for i in range(len(patterns)):
print("pattern = %s" % patterns[i])
print("outlines:")
for i in range(len(outlines)):
print("outline = %s" % outlines[i])
return True
for i in range(len(patterns)):
if not re.match(patterns[i], outlines[i]):
print(" match failed")
print("line=%d" % i)
print("expect=%s" % patterns[i])
print("actual=%s" % outlines[i])
return True
return False
def _parse_source_env(self, source):
env_match = ENV_PATTERN.search(source)
env = {}
if env_match:
for env_pair in env_match.group(1).strip().split():
var, value = env_pair.split('=')
env[var] = value
return env
def GetLabel(self):
return "%s %s" % (self.mode, self.GetName())
def GetName(self):
return self.path[-1]
def GetRunConfiguration(self):
result = [self.config.context.GetVm(self.arch, self.mode)]
source = open(self.file).read()
flags_match = FLAGS_PATTERN.search(source)
envs = self._parse_source_env(source)
if flags_match:
result += flags_match.group(1).strip().split()
result.append(self.file)
return {
'command': result,
'envs': envs
}
def GetSource(self):
return (open(self.file).read()
+ "\n--- expected output ---\n"
+ open(self.expected).read())
def RunCommand(self, command, env):
fd = None
if self.input is not None and exists(self.input):
fd = os.open(self.input, os.O_RDONLY)
full_command = self.context.processor(command)
full_command = [sys.executable, PTY_HELPER] + full_command
output = test.Execute(full_command,
self.context,
self.context.GetTimeout(self.mode),
env,
stdin=fd)
if fd is not None:
os.close(fd)
return test.TestOutput(self,
full_command,
output,
self.context.store_unexpected_output)
class TTYTestConfiguration(test.TestConfiguration):
def Ls(self, path):
if isdir(path):
return [f[:-3] for f in os.listdir(path) if f.endswith('.js')]
else:
return []
def ListTests(self, current_path, path, arch, mode):
all_tests = [current_path + [t] for t in self.Ls(self.root)]
result = []
# Skip these tests on Windows, as pseudo terminals are not available
if utils.IsWindows():
print ("Skipping pseudo-tty tests, as pseudo terminals are not available"
" on Windows.")
return result
for tst in all_tests:
if self.Contains(path, tst):
file_prefix = join(self.root, reduce(join, tst[1:], ""))
file_path = file_prefix + ".js"
input_path = file_prefix + ".in"
output_path = file_prefix + ".out"
if not exists(output_path):
raise Exception("Could not find %s" % output_path)
result.append(TTYTestCase(tst, file_path, output_path,
input_path, arch, mode, self.context, self))
return result
def GetBuildRequirements(self):
return ['sample', 'sample=shell']
def GetConfiguration(context, root):
return TTYTestConfiguration(context, root, 'pseudo-tty')