1
1
import test from 'ava' ;
2
- import * as chalk from 'chalk' ;
2
+ import chalk from 'chalk' ;
3
3
import * as cp from 'child_process' ;
4
4
import * as fs from 'fs' ;
5
5
import * as ncp from 'ncp' ;
@@ -8,14 +8,36 @@ import * as pify from 'pify';
8
8
import * as rimraf from 'rimraf' ;
9
9
import * as tmp from 'tmp' ;
10
10
11
+ interface ExecResult {
12
+ exitCode : number ;
13
+ stdout : string ;
14
+ stderr : string ;
15
+ }
16
+
11
17
const pkg = require ( '../../package.json' ) ;
12
18
13
19
const rimrafp = pify ( rimraf ) ;
14
20
const mkdirp = pify ( fs . mkdir ) ;
15
- const execp = pify ( cp . exec ) ;
21
+ const simpleExecp = pify ( cp . exec ) ;
16
22
const renamep = pify ( fs . rename ) ;
17
23
const ncpp = pify ( ncp . ncp ) ;
18
24
25
+ // cp.exec doesn't fit the (err ^ result) pattern because a process can write
26
+ // to stdout/stderr and still exit with error code != 0.
27
+ // In most cases simply promisifying cp.exec is adequate, but it's not if we
28
+ // need to see console output for a process that exited with a non-zero exit
29
+ // code, so we define a more exhaustive promsified cp.exec here.
30
+ const execp =
31
+ ( command : string , execOptions ?: cp . ExecOptions ) : Promise < ExecResult > => {
32
+ return new Promise ( ( resolve ) => {
33
+ cp . exec (
34
+ command , execOptions || { } ,
35
+ ( err : Error & { code : number } , stdout , stderr ) => {
36
+ resolve ( { exitCode : err ? err . code : 0 , stdout, stderr} ) ;
37
+ } ) ;
38
+ } ) ;
39
+ } ;
40
+
19
41
const keep = ! ! process . env . GTS_KEEP_TEMPDIRS ;
20
42
const stagingDir = tmp . dirSync ( { keep : keep , unsafeCleanup : true } ) ;
21
43
const stagingPath = stagingDir . name ;
@@ -30,43 +52,46 @@ console.log(`${chalk.blue(`${__filename} staging area: ${stagingPath}`)}`);
30
52
* to test on a fresh application.
31
53
*/
32
54
test . before ( async ( ) => {
33
- await execp ( 'npm pack' ) ;
55
+ await simpleExecp ( 'npm pack' ) ;
34
56
const tarball = `${ pkg . name } -${ pkg . version } .tgz` ;
35
57
await renamep ( tarball , `${ stagingPath } /gts.tgz` ) ;
36
58
await ncpp ( 'test/fixtures' , `${ stagingPath } /` ) ;
37
- await execp ( 'npm install' , execOpts ) ;
59
+ await simpleExecp ( 'npm install' , execOpts ) ;
38
60
} ) ;
39
61
40
62
test . serial ( 'init' , async t => {
41
- await execp ( './node_modules/.bin/gts init -y' , execOpts ) ;
63
+ await simpleExecp ( './node_modules/.bin/gts init -y' , execOpts ) ;
42
64
fs . accessSync ( `${ stagingPath } /kitchen/tsconfig.json` ) ;
43
65
t . pass ( ) ;
44
66
} ) ;
45
67
46
68
test . serial ( 'check before fix' , async t => {
47
- await t . throws ( execp ( 'npm run check' , execOpts ) ) ;
69
+ const { exitCode, stdout} = await execp ( 'npm run check' , execOpts ) ;
70
+ t . deepEqual ( exitCode , 1 ) ;
71
+ t . notDeepEqual ( stdout . indexOf ( 'clang-format reported errors' ) , - 1 ) ;
48
72
t . pass ( ) ;
49
73
} ) ;
50
74
51
75
test . serial ( 'fix' , async t => {
52
76
const preFix = fs . readFileSync ( `${ stagingPath } /kitchen/src/server.ts` , 'utf8' )
53
77
. split ( '\n' ) ;
54
- await execp ( 'npm run fix' , execOpts ) ;
78
+ await simpleExecp ( 'npm run fix' , execOpts ) ;
55
79
const postFix =
56
80
fs . readFileSync ( `${ stagingPath } /kitchen/src/server.ts` , 'utf8' )
57
81
. split ( '\n' ) ;
58
82
t . deepEqual (
59
- preFix [ 0 ] + ';' , postFix [ 0 ] ) ; // fix should have added a semi-colon
83
+ preFix [ 0 ] . trim ( ) + ';' ,
84
+ postFix [ 0 ] ) ; // fix should have added a semi-colon
60
85
t . pass ( ) ;
61
86
} ) ;
62
87
63
88
test . serial ( 'check after fix' , async t => {
64
- await execp ( 'npm run check' , execOpts ) ;
89
+ await simpleExecp ( 'npm run check' , execOpts ) ;
65
90
t . pass ( ) ;
66
91
} ) ;
67
92
68
93
test . serial ( 'build' , async t => {
69
- await execp ( 'npm run compile' , execOpts ) ;
94
+ await simpleExecp ( 'npm run compile' , execOpts ) ;
70
95
fs . accessSync ( `${ stagingPath } /kitchen/build/src/server.js` ) ;
71
96
fs . accessSync ( `${ stagingPath } /kitchen/build/src/server.js.map` ) ;
72
97
fs . accessSync ( `${ stagingPath } /kitchen/build/src/server.d.ts` ) ;
@@ -78,7 +103,7 @@ test.serial('build', async t => {
78
103
* output dir
79
104
*/
80
105
test . serial ( 'clean' , async t => {
81
- await execp ( 'npm run clean' , execOpts ) ;
106
+ await simpleExecp ( 'npm run clean' , execOpts ) ;
82
107
t . throws ( ( ) => {
83
108
fs . accessSync ( `${ stagingPath } /kitchen/build` ) ;
84
109
} ) ;
0 commit comments