11var
22 assert = require ( 'assert' ) ,
33 path = require ( 'path' ) ,
4- exec = require ( 'child_process' ) . exec ,
4+ spawn = require ( 'child_process' ) . spawn ,
55 tmp = require ( '../lib/tmp' ) ;
66
77// make sure that we do not test spam the global tmp
88tmp . TMP_DIR = './tmp' ;
99
10+ function _bufferConcat ( buffers ) {
11+ if ( Buffer . concat ) {
12+ return Buffer . concat . apply ( this , arguments ) ;
13+ } else {
14+ return new Buffer ( buffers . reduce ( function ( acc , buf ) {
15+ for ( var i = 0 ; i < buf . length ; i ++ ) {
16+ acc . push ( buf [ i ] ) ;
17+ }
18+ return acc ;
19+ } , [ ] ) ) ;
20+ }
21+ }
1022
1123function _spawnTestWithError ( testFile , params , cb ) {
1224 _spawnTest ( true , testFile , params , cb ) ;
@@ -19,25 +31,71 @@ function _spawnTestWithoutError(testFile, params, cb) {
1931function _spawnTest ( passError , testFile , params , cb ) {
2032 var
2133 node_path = process . argv [ 0 ] ,
22- command = [ node_path , path . join ( __dirname , testFile ) ] . concat ( params ) . join ( ' ' ) ;
23-
24- exec ( command , function _execDone ( err , stdout , stderr ) {
25- if ( passError ) {
26- if ( err ) {
27- return cb ( err ) ;
28- } else if ( stderr . length > 0 ) {
29- return cb ( stderr . toString ( ) ) ;
34+ command_args = [ path . join ( __dirname , testFile ) ] . concat ( params ) ,
35+ stdoutBufs = [ ] ,
36+ stderrBufs = [ ] ,
37+ child ,
38+ done = false ,
39+ stderrDone = false ,
40+ stdoutDone = false ;
41+
42+ // spawn doesn’t have the quoting problems that exec does,
43+ // especially when going for Windows portability.
44+ child = spawn ( node_path , command_args ) ;
45+ child . stdin . end ( ) ;
46+ // Cannot use 'close' event because not on node-0.6.
47+ function _close ( ) {
48+ var
49+ stderr = _bufferConcat ( stderrBufs ) ,
50+ stdout = _bufferConcat ( stdoutBufs ) ;
51+ if ( stderrDone && stdoutDone && ! done ) {
52+ done = true ;
53+ if ( passError ) {
54+ if ( stderr . length > 0 ) {
55+ return cb ( stderr . toString ( ) ) ;
56+ }
3057 }
58+ return cb ( null , _bufferConcat ( stdoutBufs ) . toString ( ) ) ;
3159 }
32-
33- return cb ( null , stdout . toString ( ) ) ;
60+ }
61+ if ( passError ) {
62+ child . on ( 'error' , function _spawnError ( err ) {
63+ if ( ! done ) {
64+ done = true ;
65+ cb ( err ) ;
66+ }
67+ } ) ;
68+ }
69+ child . stdout . on ( 'data' , function _stdoutData ( data ) {
70+ stdoutBufs . push ( data ) ;
71+ } ) . on ( 'close' , function _stdoutEnd ( ) {
72+ stdoutDone = true ;
73+ _close ( ) ;
74+ } ) ;
75+ child . stderr . on ( 'data' , function _stderrData ( data ) {
76+ stderrBufs . push ( data ) ;
77+ } ) . on ( 'close' , function _stderrEnd ( ) {
78+ stderrDone = true ;
79+ _close ( ) ;
3480 } ) ;
3581}
3682
3783function _testStat ( stat , mode ) {
38- assert . equal ( stat . uid , process . getuid ( ) , 'should have the same UID' ) ;
39- assert . equal ( stat . gid , process . getgid ( ) , 'should have the same GUID' ) ;
40- assert . equal ( stat . mode , mode ) ;
84+ // getuid() and getgid() do not exist on Windows.
85+ if ( process . getuid ) {
86+ assert . equal ( stat . uid , process . getuid ( ) , 'should have the same UID' ) ;
87+ }
88+ if ( process . getgid ) {
89+ assert . equal ( stat . gid , process . getgid ( ) , 'should have the same GUID' ) ;
90+ }
91+ // mode values do not work properly on Windows. Ignore “group” and
92+ // “other” bits then. Ignore execute bit on that platform because it
93+ // doesn’t exist—even for directories.
94+ if ( process . platform == 'win32' ) {
95+ assert . equal ( stat . mode & 0666600 , mode & 0666600 ) ;
96+ } else {
97+ assert . equal ( stat . mode , mode ) ;
98+ }
4199}
42100
43101function _testPrefix ( prefix ) {
0 commit comments