Skip to content

Commit f3a4d03

Browse files
dario-piotrowiczaduh95
authored andcommitted
test: add tests for REPL custom evals
PR-URL: #57691 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 23c4e94 commit f3a4d03

3 files changed

Lines changed: 135 additions & 34 deletions

File tree

‎lib/repl.js‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,6 @@ function REPLServer(prompt,
306306
options.useColors=shouldColorize(options.output);
307307
}
308308

309-
// TODO(devsnek): Add a test case for custom eval functions.
310309
constpreview=options.terminal&&
311310
(options.preview!==undefined ? !!options.preview : !eval_);
312311

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
'use strict';
2+
3+
require('../common');
4+
constArrayStream=require('../common/arraystream');
5+
constassert=require('assert');
6+
const{ describe, it }=require('node:test');
7+
8+
constrepl=require('repl');
9+
10+
functiongetReplOutput(input,replOptions,run=true){
11+
constinputStream=newArrayStream();
12+
constoutputStream=newArrayStream();
13+
14+
repl.start({
15+
input: inputStream,
16+
output: outputStream,
17+
...replOptions,
18+
});
19+
20+
letoutput='';
21+
outputStream.write=(chunk)=>(output+=chunk);
22+
23+
inputStream.emit('data',input);
24+
25+
if(run){
26+
inputStream.run(['']);
27+
}
28+
29+
returnoutput;
30+
}
31+
32+
describe('repl with custom eval',{concurrency: true},()=>{
33+
it('uses the custom eval function as expected',()=>{
34+
constoutput=getReplOutput('Convert this to upper case',{
35+
terminal: true,
36+
eval: (code,_ctx,_replRes,cb)=>cb(null,code.toUpperCase()),
37+
});
38+
assert.match(
39+
output,
40+
/Convertthistouppercase\r\n'CONVERTTHISTOUPPERCASE\\n'/
41+
);
42+
});
43+
44+
it('surfaces errors as expected',()=>{
45+
constoutput=getReplOutput('Convert this to upper case',{
46+
terminal: true,
47+
eval: (_code,_ctx,_replRes,cb)=>cb(newError('Testing Error')),
48+
});
49+
assert.match(output,/UncaughtError:TestingError\n/);
50+
});
51+
52+
it('provides a repl context to the eval callback',async()=>{
53+
constcontext=awaitnewPromise((resolve)=>{
54+
constr=repl.start({
55+
eval: (_cmd,context)=>resolve(context),
56+
});
57+
r.context={foo: 'bar'};
58+
r.write('\n.exit\n');
59+
});
60+
assert.strictEqual(context.foo,'bar');
61+
});
62+
63+
it('provides the global context to the eval callback',async()=>{
64+
constcontext=awaitnewPromise((resolve)=>{
65+
constr=repl.start({
66+
useGlobal: true,
67+
eval: (_cmd,context)=>resolve(context),
68+
});
69+
global.foo='global_foo';
70+
r.write('\n.exit\n');
71+
});
72+
73+
assert.strictEqual(context.foo,'global_foo');
74+
deleteglobal.foo;
75+
});
76+
77+
it('inherits variables from the global context but does not use it afterwords if `useGlobal` is false',async()=>{
78+
global.bar='global_bar';
79+
constcontext=awaitnewPromise((resolve)=>{
80+
constr=repl.start({
81+
useGlobal: false,
82+
eval: (_cmd,context)=>resolve(context),
83+
});
84+
global.baz='global_baz';
85+
r.write('\n.exit\n');
86+
});
87+
88+
assert.strictEqual(context.bar,'global_bar');
89+
assert.notStrictEqual(context.baz,'global_baz');
90+
deleteglobal.bar;
91+
deleteglobal.baz;
92+
});
93+
94+
/**
95+
* Default preprocessor transforms
96+
* function f() {} to
97+
* var f = function f() {}
98+
* This test ensures that original input is preserved.
99+
* Reference: https://github.com/nodejs/node/issues/9743
100+
*/
101+
it('preserves the original input',async()=>{
102+
constcmd=awaitnewPromise((resolve)=>{
103+
constr=repl.start({
104+
eval: (cmd)=>resolve(cmd),
105+
});
106+
r.write('function f() {}\n.exit\n');
107+
});
108+
assert.strictEqual(cmd,'function f() {}\n');
109+
});
110+
111+
it("doesn't show previews by default",()=>{
112+
constinput="'Hello custom' + ' eval World!'";
113+
constoutput=getReplOutput(input,{
114+
terminal: true,
115+
eval: (code,_ctx,_replRes,cb)=>cb(null,eval(code)),
116+
},false);
117+
assert.strictEqual(output,input);
118+
assert.doesNotMatch(output,/HellocustomevalWorld!/);
119+
});
120+
121+
it('does show previews if `preview` is set to `true`',()=>{
122+
constinput="'Hello custom' + ' eval World!'";
123+
constoutput=getReplOutput(input,{
124+
terminal: true,
125+
eval: (code,_ctx,_replRes,cb)=>cb(null,eval(code)),
126+
preview: true,
127+
},false);
128+
129+
constescapedInput=input.replace(/\+/g,'\\+');// TODO: migrate to `RegExp.escape` when it's available.
130+
assert.match(
131+
output,
132+
newRegExp(`${escapedInput}\n// 'Hello custom eval World!'`)
133+
);
134+
});
135+
});

‎test/parallel/test-repl-eval.js‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)