Skip to content

Commit b7e488c

Browse files
dario-piotrowicztargos
authored andcommitted
test: refactor repl tab complete tests
refactor the test/parallel/test-repl-tab-complete.js file by: - making the tests in the file self-contained (instead of all of them sharing the same REPL instance and constantly calling `.clear` on it) - using the test runner with appropriate descriptions to make clearer what is being tested - extracting some tests in their own js test files (to increase isolation of the tests and help with issues such as flakiness) PR-URL: #58636 Reviewed-By: Giovanni Bucci <github@puskin.it> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent ef0230a commit b7e488c

6 files changed

Lines changed: 1003 additions & 734 deletions
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constArrayStream=require('../common/arraystream');
5+
const{ hijackStderr, restoreStderr }=require('../common/hijackstdio');
6+
constassert=require('assert');
7+
8+
constrepl=require('repl');
9+
10+
constinput=newArrayStream();
11+
constreplServer=repl.start({
12+
prompt: '',
13+
input,
14+
output: process.stdout,
15+
allowBlockingCompletions: true,
16+
});
17+
18+
// Some errors are passed to the domain, but do not callback
19+
replServer._domain.on('error',assert.ifError);
20+
21+
for(consttypeof[
22+
Array,
23+
Buffer,
24+
25+
Uint8Array,
26+
Uint16Array,
27+
Uint32Array,
28+
29+
Uint8ClampedArray,
30+
Int8Array,
31+
Int16Array,
32+
Int32Array,
33+
Float32Array,
34+
Float64Array,
35+
]){
36+
input.run(['.clear']);
37+
38+
if(type===Array){
39+
input.run([
40+
'var ele = [];',
41+
'for (let i = 0; i < 1e6 + 1; i++) ele[i] = 0;',
42+
'ele.biu = 1;',
43+
]);
44+
}elseif(type===Buffer){
45+
input.run(['var ele = Buffer.alloc(1e6 + 1); ele.biu = 1;']);
46+
}else{
47+
input.run([`var ele = new ${type.name}(1e6 + 1); ele.biu = 1;`]);
48+
}
49+
50+
hijackStderr(common.mustNotCall());
51+
replServer.complete(
52+
'ele.',
53+
common.mustCall((err,data)=>{
54+
restoreStderr();
55+
assert.ifError(err);
56+
57+
constele=
58+
type===Array ? [] : type===Buffer ? Buffer.alloc(0) : newtype(0);
59+
60+
assert.strictEqual(data[0].includes('ele.biu'),true);
61+
62+
data[0].forEach((key)=>{
63+
if(!key||key==='ele.biu')return;
64+
assert.notStrictEqual(ele[key.slice(4)],undefined);
65+
});
66+
})
67+
);
68+
}
69+
70+
// check Buffer.prototype.length not crashing.
71+
// Refs: https://github.com/nodejs/node/pull/11961
72+
input.run(['.clear']);
73+
replServer.complete('Buffer.prototype.',common.mustCall());
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constArrayStream=require('../common/arraystream');
5+
constassert=require('assert');
6+
7+
constrepl=require('repl');
8+
9+
constputIn=newArrayStream();
10+
11+
// To test custom completer function.
12+
// Sync mode.
13+
{
14+
constcustomCompletions='aaa aa1 aa2 bbb bb1 bb2 bb3 ccc ddd eee'.split(' ');
15+
consttestCustomCompleterSyncMode=repl.start({
16+
prompt: '',
17+
input: putIn,
18+
output: putIn,
19+
completer: functioncompleter(line){
20+
consthits=customCompletions.filter((c)=>c.startsWith(line));
21+
// Show all completions if none found.
22+
return[hits.length ? hits : customCompletions,line];
23+
}
24+
});
25+
26+
// On empty line should output all the custom completions
27+
// without complete anything.
28+
testCustomCompleterSyncMode.complete('',common.mustCall((error,data)=>{
29+
assert.deepStrictEqual(data,[
30+
customCompletions,
31+
'',
32+
]);
33+
}));
34+
35+
// On `a` should output `aaa aa1 aa2` and complete until `aa`.
36+
testCustomCompleterSyncMode.complete('a',common.mustCall((error,data)=>{
37+
assert.deepStrictEqual(data,[
38+
'aaa aa1 aa2'.split(' '),
39+
'a',
40+
]);
41+
}));
42+
}
43+
44+
// To test custom completer function.
45+
// Async mode.
46+
{
47+
constcustomCompletions='aaa aa1 aa2 bbb bb1 bb2 bb3 ccc ddd eee'.split(' ');
48+
consttestCustomCompleterAsyncMode=repl.start({
49+
prompt: '',
50+
input: putIn,
51+
output: putIn,
52+
completer: functioncompleter(line,callback){
53+
consthits=customCompletions.filter((c)=>c.startsWith(line));
54+
// Show all completions if none found.
55+
callback(null,[hits.length ? hits : customCompletions,line]);
56+
}
57+
});
58+
59+
// On empty line should output all the custom completions
60+
// without complete anything.
61+
testCustomCompleterAsyncMode.complete('',common.mustCall((error,data)=>{
62+
assert.deepStrictEqual(data,[
63+
customCompletions,
64+
'',
65+
]);
66+
}));
67+
68+
// On `a` should output `aaa aa1 aa2` and complete until `aa`.
69+
testCustomCompleterAsyncMode.complete('a',common.mustCall((error,data)=>{
70+
assert.deepStrictEqual(data,[
71+
'aaa aa1 aa2'.split(' '),
72+
'a',
73+
]);
74+
}));
75+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constArrayStream=require('../common/arraystream');
5+
constassert=require('assert');
6+
constpath=require('path');
7+
8+
const{ isMainThread }=require('worker_threads');
9+
10+
if(!isMainThread){
11+
common.skip('process.chdir is not available in Workers');
12+
}
13+
14+
constrepl=require('repl');
15+
16+
constreplServer=repl.start({
17+
prompt: '',
18+
input: newArrayStream(),
19+
output: process.stdout,
20+
allowBlockingCompletions: true,
21+
});
22+
23+
// Some errors are passed to the domain, but do not callback
24+
replServer._domain.on('error',assert.ifError);
25+
26+
// Tab completion for files/directories
27+
{
28+
process.chdir(__dirname);
29+
30+
constreadFileSyncs=['fs.readFileSync("','fs.promises.readFileSync("'];
31+
if(!common.isWindows){
32+
readFileSyncs.forEach((readFileSync)=>{
33+
constfixturePath=`${readFileSync}../fixtures/test-repl-tab-completion`;
34+
replServer.complete(
35+
fixturePath,
36+
common.mustCall((err,data)=>{
37+
assert.strictEqual(err,null);
38+
assert.ok(data[0][0].includes('.hiddenfiles'));
39+
assert.ok(data[0][1].includes('hellorandom.txt'));
40+
assert.ok(data[0][2].includes('helloworld.js'));
41+
})
42+
);
43+
44+
replServer.complete(
45+
`${fixturePath}/hello`,
46+
common.mustCall((err,data)=>{
47+
assert.strictEqual(err,null);
48+
assert.ok(data[0][0].includes('hellorandom.txt'));
49+
assert.ok(data[0][1].includes('helloworld.js'));
50+
})
51+
);
52+
53+
replServer.complete(
54+
`${fixturePath}/.h`,
55+
common.mustCall((err,data)=>{
56+
assert.strictEqual(err,null);
57+
assert.ok(data[0][0].includes('.hiddenfiles'));
58+
})
59+
);
60+
61+
replServer.complete(
62+
`${readFileSync}./xxxRandom/random`,
63+
common.mustCall((err,data)=>{
64+
assert.strictEqual(err,null);
65+
assert.strictEqual(data[0].length,0);
66+
})
67+
);
68+
69+
consttestPath=fixturePath.slice(0,-1);
70+
replServer.complete(
71+
testPath,
72+
common.mustCall((err,data)=>{
73+
assert.strictEqual(err,null);
74+
assert.ok(data[0][0].includes('test-repl-tab-completion'));
75+
assert.strictEqual(data[1],path.basename(testPath));
76+
})
77+
);
78+
});
79+
}
80+
}
Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,48 @@
11
'use strict';
22

3-
require('../common');
3+
constcommon=require('../common');
4+
constassert=require('assert');
45
constArrayStream=require('../common/arraystream');
56
constrepl=require('repl');
67

7-
conststream=newArrayStream();
8-
constreplServer=repl.start({
9-
input: stream,
10-
output: stream,
11-
terminal: true,
12-
});
8+
// Tab completion in editor mode
9+
{
10+
consteditorStream=newArrayStream();
11+
consteditor=repl.start({
12+
stream: editorStream,
13+
terminal: true,
14+
useColors: false
15+
});
1316

14-
// Editor mode
15-
replServer.write('.editor\n');
17+
editorStream.run(['.clear']);
18+
editorStream.run(['.editor']);
19+
20+
editor.completer('Uin',common.mustCall((_error,data)=>{
21+
assert.deepStrictEqual(data,[['Uint'],'Uin']);
22+
}));
23+
24+
editorStream.run(['.clear']);
25+
editorStream.run(['.editor']);
26+
27+
editor.completer('var log = console.l',common.mustCall((_error,data)=>{
28+
assert.deepStrictEqual(data,[['console.log'],'console.l']);
29+
}));
30+
}
1631

1732
// Regression test for https://github.com/nodejs/node/issues/43528
18-
replServer.write('a');
19-
replServer.write(null,{name: 'tab'});// Should not throw
33+
{
34+
conststream=newArrayStream();
35+
constreplServer=repl.start({
36+
input: stream,
37+
output: stream,
38+
terminal: true,
39+
});
40+
41+
// Editor mode
42+
replServer.write('.editor\n');
43+
44+
replServer.write('a');
45+
replServer.write(null,{name: 'tab'});// Should not throw
2046

21-
replServer.close();
47+
replServer.close();
48+
}

0 commit comments

Comments
 (0)