44 *-----------------------------------------------------------------------------------------------*/
55
66import * as chai from 'chai' ;
7- import { ExecException , ExecOptions } from 'child_process' ;
7+ import { ExecOptions } from 'child_process' ;
88import * as sinon from 'sinon' ;
99import sinonChai from 'sinon-chai' ;
10- import * as vscode from 'vscode ' ;
10+ import { EventEmitter , PassThrough } from 'stream ' ;
1111import { ChildProcessUtil } from '../../../src/util/childProcessUtil' ;
1212import { Util as childProcess } from '../../../src/util/utils' ;
1313
@@ -16,48 +16,77 @@ chai.use(sinonChai);
1616
1717suite ( 'ChildProcessUtil' , function ( ) {
1818 let sandbox : sinon . SinonSandbox ;
19- let execStub : sinon . SinonStub ;
20- const childProcessUtil = ChildProcessUtil . Instance ;
19+ let spawnStub : sinon . SinonStub ;
2120 const command = 'command' ;
2221 const options : ExecOptions = { cwd : 'cwd' } ;
2322 const stdout = 'Standard output' ;
2423 const stderr = 'Error output' ;
25- const error : ExecException = {
26- message : 'Fatal Error' ,
27- name : 'name'
28- } ;
2924
3025 setup ( function ( ) {
3126 sandbox = sinon . createSandbox ( ) ;
32- execStub = sandbox . stub ( childProcess , 'exec' ) ;
3327 } ) ;
3428
3529 teardown ( function ( ) {
3630 sandbox . restore ( ) ;
3731 } ) ;
3832
33+ function createFakeProcess ( ) {
34+ const fake : any = new EventEmitter ( ) ;
35+ fake . stdout = new PassThrough ( ) ;
36+ fake . stderr = new PassThrough ( ) ;
37+ fake . stdin = new PassThrough ( ) ;
38+ return fake ;
39+ }
40+
3941 test ( 'execute runs the given command from shell' , async function ( ) {
40- execStub . yields ( null , stdout , '' ) ;
41- const result = await childProcessUtil . execute ( command , options ) ;
42+ const fakeProcess : any = createFakeProcess ( ) ;
43+ spawnStub = sandbox . stub ( childProcess , 'spawn' ) . returns ( fakeProcess ) ;
4244
43- expect ( execStub ) . calledWithExactly ( command , options , sinon . match . func ) ;
44- expect ( result ) . deep . equals ( { error : null , stdout, stderr : '' , cwd : 'cwd' } ) ;
45- } ) ;
45+ // create util AFTER stubbing
46+ const childProcessUtil = ChildProcessUtil . Instance ;
4647
47- test ( 'execute uses a 2MB buffer by default' , async function ( ) {
48- // Change Exec Max Buffer Length to 2Mb (while the default value is 4Gb)
49- await vscode . workspace . getConfiguration ( 'openshiftToolkit' ) . update ( 'execMaxBufferLength' , 2 ) ;
48+ // simulate normal completion
49+ setImmediate ( ( ) => {
50+ fakeProcess . stdout . emit ( 'data' , stdout ) ;
51+ fakeProcess . stderr . emit ( 'data' , '' ) ;
52+ fakeProcess . emit ( 'close' , 0 ) ;
53+ } ) ;
54+
55+ const result = await childProcessUtil . execute ( command , options ) ;
5056
51- execStub . yields ( null , stdout , '' ) ;
52- await childProcessUtil . execute ( command ) ;
57+ sinon . assert . calledOnce ( spawnStub ) ;
58+ sinon . assert . calledWith ( spawnStub , command , sinon . match ( { shell : true , cwd : 'cwd' } ) ) ;
5359
54- expect ( execStub ) . calledOnceWith ( command , { maxBuffer : 2 * 1024 * 1024 } , sinon . match . func ) ;
60+ expect ( result ) . deep . equals ( {
61+ error : undefined ,
62+ stdout : 'Standard output' ,
63+ stderr : '' ,
64+ cwd : 'cwd'
65+ } ) ;
5566 } ) ;
5667
5768 test ( 'execute passes errors into its exit data' , async function ( ) {
58- execStub . yields ( error , stdout , stderr ) ;
69+ const fakeProcess : any = createFakeProcess ( ) ;
70+ spawnStub = sandbox . stub ( childProcess , 'spawn' ) . returns ( fakeProcess ) ;
71+
72+ // create util AFTER stubbing
73+ const childProcessUtil = ChildProcessUtil . Instance ;
74+
75+ // simulate error output + non-zero exit
76+ setTimeout ( ( ) => {
77+ fakeProcess . stdout . write ( stdout ) ;
78+ fakeProcess . stderr . write ( stderr ) ;
79+ fakeProcess . emit ( 'close' , 1 ) ;
80+ } , 0 ) ;
81+
5982 const result = await childProcessUtil . execute ( command ) ;
6083
61- expect ( result ) . deep . equals ( { error, stdout, stderr , cwd : undefined } ) ;
84+ sinon . assert . calledOnce ( spawnStub ) ;
85+ sinon . assert . calledWith ( spawnStub , command , sinon . match ( { shell : true } ) ) ;
86+
87+ expect ( result . error ) . to . be . instanceOf ( Error ) . and . have . property ( 'message' , 'Exited with code 1' ) ;
88+ expect ( result . stdout ) . to . equal ( stdout ) ;
89+ expect ( result . stderr ) . to . equal ( stderr ) ;
90+ expect ( result . cwd ) . to . be . undefined ;
6291 } ) ;
6392} ) ;
0 commit comments