node/test/parallel/test-repl-history-navigation.js
Ruben Bridgewater f8763bb077
benchmark,doc,lib,test: capitalize comments
PR-URL: https://github.com/nodejs/node/pull/26483
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
2019-03-10 00:44:40 +01:00

140 lines
3.2 KiB
JavaScript

'use strict';
// Flags: --expose-internals
const common = require('../common');
const stream = require('stream');
const REPL = require('internal/repl');
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
const defaultHistoryPath = path.join(tmpdir.path, '.node_repl_history');
// Create an input stream specialized for testing an array of actions
class ActionStream extends stream.Stream {
run(data) {
const _iter = data[Symbol.iterator]();
const doAction = () => {
const next = _iter.next();
if (next.done) {
// Close the repl. Note that it must have a clean prompt to do so.
this.emit('keypress', '', { ctrl: true, name: 'd' });
return;
}
const action = next.value;
if (typeof action === 'object') {
this.emit('keypress', '', action);
} else {
this.emit('data', `${action}`);
}
setImmediate(doAction);
};
setImmediate(doAction);
}
resume() {}
pause() {}
}
ActionStream.prototype.readable = true;
// Mock keys
const ENTER = { name: 'enter' };
const UP = { name: 'up' };
const DOWN = { name: 'down' };
const prompt = '> ';
const tests = [
{ // Creates few history to navigate for
env: { NODE_REPL_HISTORY: defaultHistoryPath },
test: [ 'let ab = 45', ENTER,
'555 + 909', ENTER,
'{key : {key2 :[] }}', ENTER],
expected: [],
clean: false
},
{
env: { NODE_REPL_HISTORY: defaultHistoryPath },
test: [UP, UP, UP, UP, DOWN, DOWN, DOWN],
expected: [prompt,
`${prompt}{key : {key2 :[] }}`,
`${prompt}555 + 909`,
`${prompt}let ab = 45`,
`${prompt}555 + 909`,
`${prompt}{key : {key2 :[] }}`,
prompt],
clean: true
}
];
const numtests = tests.length;
const runTestWrap = common.mustCall(runTest, numtests);
function cleanupTmpFile() {
try {
// Write over the file, clearing any history
fs.writeFileSync(defaultHistoryPath, '');
} catch (err) {
if (err.code === 'ENOENT') return true;
throw err;
}
return true;
}
function runTest() {
const opts = tests.shift();
if (!opts) return; // All done
const env = opts.env;
const test = opts.test;
const expected = opts.expected;
REPL.createInternalRepl(env, {
input: new ActionStream(),
output: new stream.Writable({
write(chunk, _, next) {
const output = chunk.toString();
if (output.charCodeAt(0) === 27 || /^[\r\n]+$/.test(output)) {
return next();
}
if (expected.length) {
assert.strictEqual(output, expected[0]);
expected.shift();
}
next();
}
}),
prompt: prompt,
useColors: false,
terminal: true
}, function(err, repl) {
if (err) {
console.error(`Failed test # ${numtests - tests.length}`);
throw err;
}
repl.once('close', () => {
if (opts.clean)
cleanupTmpFile();
if (expected.length !== 0) {
throw new Error(`Failed test # ${numtests - tests.length}`);
}
setImmediate(runTestWrap, true);
});
repl.inputStream.run(test);
});
}
// run the tests
runTest();